change streaming support back to RestTemplate
This commit is contained in:
parent
11c79d55d8
commit
ccced32e1d
7 changed files with 100 additions and 110 deletions
4
pom.xml
4
pom.xml
|
@ -266,10 +266,6 @@
|
|||
<artifactId>spring-security-jwt</artifactId>
|
||||
<version>1.0.9.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache HTTP -->
|
||||
<dependency>
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -49,25 +51,32 @@ public abstract class AbstractDownloadServiceHandler implements DownloadServiceH
|
|||
configId,
|
||||
downloadFileName);
|
||||
|
||||
final byte[] configFile = webserviceCall(configId);
|
||||
|
||||
if (configFile == null) {
|
||||
log.error("No or empty download received from webservice. Download request is ignored");
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Sucessfully downloaded from webservice. File size: {}", configFile.length);
|
||||
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setContentLength(configFile.length);
|
||||
|
||||
final String header =
|
||||
"attachment; filename=\"" + Utils.preventResponseSplittingAttack(downloadFileName) + "\"";
|
||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, header);
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
|
||||
log.debug("Write the download data to response output");
|
||||
webserviceCall(configId, response.getOutputStream());
|
||||
|
||||
response.getOutputStream().write(configFile);
|
||||
// final byte[] configFile = webserviceCall(configId);
|
||||
//
|
||||
// if (configFile == null) {
|
||||
// log.error("No or empty download received from webservice. Download request is ignored");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// log.debug("Sucessfully downloaded from webservice. File size: {}", configFile.length);
|
||||
//
|
||||
// response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
// response.setContentLength(configFile.length);
|
||||
//
|
||||
// final String header =
|
||||
// "attachment; filename=\"" + Utils.preventResponseSplittingAttack(downloadFileName) + "\"";
|
||||
// response.setHeader(HttpHeaders.CONTENT_DISPOSITION, header);
|
||||
//
|
||||
// log.debug("Write the download data to response output");
|
||||
//
|
||||
// response.getOutputStream().write(configFile);
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error(
|
||||
|
@ -76,6 +85,6 @@ public abstract class AbstractDownloadServiceHandler implements DownloadServiceH
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract byte[] webserviceCall(String configId);
|
||||
protected abstract void webserviceCall(String configId, OutputStream downloadOut);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -22,6 +29,8 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.
|
|||
@GuiProfile
|
||||
public class SebClientConfigDownload extends AbstractDownloadServiceHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SebClientConfigDownload.class);
|
||||
|
||||
private final RestService restService;
|
||||
public final String downloadFileName;
|
||||
|
||||
|
@ -34,11 +43,27 @@ public class SebClientConfigDownload extends AbstractDownloadServiceHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected byte[] webserviceCall(final String modelId) {
|
||||
return this.restService.getBuilder(ExportClientConfig.class)
|
||||
protected void webserviceCall(final String modelId, final OutputStream downloadOut) {
|
||||
|
||||
final InputStream input = this.restService.getBuilder(ExportClientConfig.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, modelId)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
try {
|
||||
IOUtils.copyLarge(input, downloadOut);
|
||||
} catch (final IOException e) {
|
||||
log.error(
|
||||
"Unexpected error while streaming incomming config data from web-service to output-stream of download response: ",
|
||||
e);
|
||||
} finally {
|
||||
try {
|
||||
downloadOut.flush();
|
||||
downloadOut.close();
|
||||
} catch (final IOException e) {
|
||||
log.error("Unexpected error while trying to close download output-stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -21,6 +28,8 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.Ex
|
|||
@GuiProfile
|
||||
public class SebExamConfigDownload extends AbstractDownloadServiceHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SebExamConfigDownload.class);
|
||||
|
||||
private final RestService restService;
|
||||
|
||||
protected SebExamConfigDownload(final RestService restService) {
|
||||
|
@ -28,11 +37,27 @@ public class SebExamConfigDownload extends AbstractDownloadServiceHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected byte[] webserviceCall(final String modelId) {
|
||||
return this.restService.getBuilder(ExportPlainXML.class)
|
||||
protected void webserviceCall(final String modelId, final OutputStream downloadOut) {
|
||||
|
||||
final InputStream input = this.restService.getBuilder(ExportPlainXML.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, modelId)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
try {
|
||||
IOUtils.copyLarge(input, downloadOut);
|
||||
} catch (final IOException e) {
|
||||
log.error(
|
||||
"Unexpected error while streaming incomming config data from web-service to output-stream of download response: ",
|
||||
e);
|
||||
} finally {
|
||||
try {
|
||||
downloadOut.flush();
|
||||
downloadOut.close();
|
||||
} catch (final IOException e) {
|
||||
log.error("Unexpected error while trying to close download output-stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,25 +8,19 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
||||
public abstract class AbstractExportCall extends RestCall<byte[]> {
|
||||
public abstract class AbstractExportCall extends RestCall<InputStream> {
|
||||
|
||||
protected AbstractExportCall(
|
||||
final TypeKey<byte[]> typeKey,
|
||||
final TypeKey<InputStream> typeKey,
|
||||
final HttpMethod httpMethod,
|
||||
final MediaType contentType,
|
||||
final String path) {
|
||||
|
@ -34,85 +28,22 @@ public abstract class AbstractExportCall extends RestCall<byte[]> {
|
|||
super(typeKey, httpMethod, contentType, path);
|
||||
}
|
||||
|
||||
// We need a WebClient here to separate the request from the usual RestTemplate
|
||||
// and allow also to get async responses
|
||||
// The OAut2 bearer is get from the current OAuth2RestTemplate
|
||||
// TODO create better API for this on RestCallBuilder site
|
||||
@Override
|
||||
protected Result<byte[]> exchange(final RestCallBuilder builder) {
|
||||
try {
|
||||
protected Result<InputStream> exchange(final RestCallBuilder builder) {
|
||||
|
||||
final OAuth2RestTemplate restTemplate = (OAuth2RestTemplate) builder.getRestTemplate();
|
||||
final OAuth2AccessToken accessToken = restTemplate.getAccessToken();
|
||||
final String value = accessToken.getValue();
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
WebClient.create()
|
||||
.method(this.httpMethod)
|
||||
.uri(
|
||||
return builder
|
||||
.getRestTemplate()
|
||||
.execute(
|
||||
builder.buildURI(),
|
||||
builder.getURIVariables())
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + value)
|
||||
.headers(h -> h.addAll(builder.buildRequestEntity().getHeaders()))
|
||||
.body(BodyInserters.fromObject("grant_type=client_credentials&scope=read,write"))
|
||||
.accept(MediaType.APPLICATION_OCTET_STREAM)
|
||||
.retrieve()
|
||||
.bodyToFlux(DataBuffer.class)
|
||||
.map(source -> {
|
||||
this.httpMethod,
|
||||
(final ClientHttpRequest requestCallback) -> {
|
||||
},
|
||||
response -> IOUtils.toBufferedInputStream(response.getBody()),
|
||||
builder.getURIVariables());
|
||||
|
||||
try {
|
||||
IOUtils.copyLarge(source.asInputStream(), byteArrayOutputStream);
|
||||
} catch (final IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return source;
|
||||
})
|
||||
.blockLast();
|
||||
|
||||
final byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
|
||||
return Result.of(byteArray);
|
||||
|
||||
// final byte[] value = builder
|
||||
// .getRestTemplate()
|
||||
// .execute(
|
||||
// builder.buildURI(),
|
||||
// this.httpMethod,
|
||||
// request -> {
|
||||
// },
|
||||
// response -> {
|
||||
// final InputStream input = IOUtils.toBufferedInputStream(response.getBody());
|
||||
// final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
// IOUtils.copyLarge(input, output);
|
||||
// return output.toByteArray();
|
||||
// },
|
||||
// builder.getURIVariables());
|
||||
//
|
||||
// System.out.println("************************ getResponse " + Utils.toString(value));
|
||||
//
|
||||
// return Result.of(value);
|
||||
//
|
||||
// final ResponseEntity<byte[]> responseEntity = builder
|
||||
// .getRestTemplate()
|
||||
// .exchange(
|
||||
// builder.buildURI(),
|
||||
// this.httpMethod,
|
||||
// builder.buildRequestEntity(),
|
||||
// byte[].class,
|
||||
// builder.getURIVariables());
|
||||
|
||||
// if (responseEntity.getStatusCode() == HttpStatus.OK) {
|
||||
// final byte[] body = responseEntity.getBody();
|
||||
// System.out.println("************************ getResponse " + Utils.toString(body));
|
||||
// return Result.of(body);
|
||||
// }
|
||||
//
|
||||
// return Result.ofRuntimeError(
|
||||
// "Error while trying to export from webservice. Response: " + responseEntity);
|
||||
} catch (final Throwable t) {
|
||||
return Result.ofError(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -29,7 +31,7 @@ public class ExportClientConfig extends AbstractExportCall {
|
|||
super(new TypeKey<>(
|
||||
CallType.UNDEFINED,
|
||||
EntityType.SEB_CLIENT_CONFIGURATION,
|
||||
new TypeReference<byte[]>() {
|
||||
new TypeReference<InputStream>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -29,7 +31,7 @@ public class ExportPlainXML extends AbstractExportCall {
|
|||
super(new TypeKey<>(
|
||||
CallType.UNDEFINED,
|
||||
EntityType.CONFIGURATION_NODE,
|
||||
new TypeReference<byte[]>() {
|
||||
new TypeReference<InputStream>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
|
|
Loading…
Reference in a new issue