fixed streaming download for SEB Log export
This commit is contained in:
		
							parent
							
								
									f44c82bde3
								
							
						
					
					
						commit
						614f4430d2
					
				
					 6 changed files with 81 additions and 32 deletions
				
			
		|  | @ -55,26 +55,32 @@ public class SEBClientLogExport extends AbstractDownloadServiceHandler { | |||
|             queryParams.add(param, String.valueOf(request.getParameter(param))); | ||||
|         } | ||||
| 
 | ||||
|         final InputStream input = this.restService | ||||
|         this.restService | ||||
|                 .getBuilder(ExportSEBClientLogs.class) | ||||
|                 .withResponseExtractor(response -> { | ||||
| 
 | ||||
|                     try { | ||||
|                         final InputStream input = response.getBody(); | ||||
|                         IOUtils.copyLarge(input, downloadOut); | ||||
|                     } catch (final IOException e) { | ||||
|                         log.error( | ||||
|                                 "Unexpected error while streaming incoming 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"); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     return true; | ||||
|                 }) | ||||
|                 .withQueryParams(queryParams) | ||||
|                 .call() | ||||
|                 .getOrThrow(); | ||||
|                 .onError(error -> log.error("Download failed: ", error)); | ||||
| 
 | ||||
|         try { | ||||
|             IOUtils.copyLarge(input, downloadOut); | ||||
|         } catch (final IOException e) { | ||||
|             log.error( | ||||
|                     "Unexpected error while streaming incoming 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"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,43 @@ | |||
| /* | ||||
|  * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET) | ||||
|  * | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| package ch.ethz.seb.sebserver.gui.service.remote.webservice.api; | ||||
| 
 | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.client.ClientHttpRequest; | ||||
| 
 | ||||
| import com.fasterxml.jackson.core.type.TypeReference; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.util.Result; | ||||
| 
 | ||||
| public class AbstractDownloadCall extends RestCall<Boolean> { | ||||
| 
 | ||||
|     protected AbstractDownloadCall( | ||||
|             final MediaType contentType, | ||||
|             final String path) { | ||||
| 
 | ||||
|         super(new RestCall.TypeKey<>(CallType.UNDEFINED, null, new TypeReference<Boolean>() { | ||||
|         }), HttpMethod.GET, contentType, path); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected Result<Boolean> exchange(final RestCallBuilder builder) { | ||||
| 
 | ||||
|         return Result.tryCatch(() -> builder | ||||
|                 .getRestTemplate() | ||||
|                 .execute( | ||||
|                         builder.buildURI(), | ||||
|                         this.httpMethod, | ||||
|                         (final ClientHttpRequest requestCallback) -> { | ||||
|                         }, | ||||
|                         builder.getResponseExtractor(), | ||||
|                         builder.getURIVariables())); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -17,6 +17,7 @@ import org.springframework.http.client.ClientHttpRequest; | |||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.util.Result; | ||||
| 
 | ||||
| @Deprecated(since = "1.2. : This is not streaming correctly. Use AbstractDownloadCall instead") | ||||
| public abstract class AbstractExportCall extends RestCall<InputStream> { | ||||
| 
 | ||||
|     protected AbstractExportCall( | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ import org.springframework.http.ResponseEntity; | |||
| import org.springframework.util.LinkedMultiValueMap; | ||||
| import org.springframework.util.MultiValueMap; | ||||
| import org.springframework.web.client.ResourceAccessException; | ||||
| import org.springframework.web.client.ResponseExtractor; | ||||
| import org.springframework.web.client.RestClientResponseException; | ||||
| import org.springframework.web.client.RestTemplate; | ||||
| import org.springframework.web.util.UriComponentsBuilder; | ||||
|  | @ -224,6 +225,7 @@ public abstract class RestCall<T> { | |||
|         private final HttpHeaders httpHeaders; | ||||
|         private String body = null; | ||||
|         private InputStream streamingBody = null; | ||||
|         private ResponseExtractor<Boolean> responseExtractor = null; | ||||
| 
 | ||||
|         private final MultiValueMap<String, String> queryParams; | ||||
|         private final Map<String, String> uriVariables; | ||||
|  | @ -253,6 +255,15 @@ public abstract class RestCall<T> { | |||
|             return this.restTemplate; | ||||
|         } | ||||
| 
 | ||||
|         public RestCallBuilder withResponseExtractor(final ResponseExtractor<Boolean> responseExtractor) { | ||||
|             this.responseExtractor = responseExtractor; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public ResponseExtractor<Boolean> getResponseExtractor() { | ||||
|             return this.responseExtractor; | ||||
|         } | ||||
| 
 | ||||
|         public RestCallBuilder withRestTemplate(final RestTemplate restTemplate) { | ||||
|             this.restTemplate = restTemplate; | ||||
|             return this; | ||||
|  |  | |||
|  | @ -8,33 +8,21 @@ | |||
| 
 | ||||
| package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam; | ||||
| 
 | ||||
| import java.io.InputStream; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import com.fasterxml.jackson.core.type.TypeReference; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.api.API; | ||||
| import ch.ethz.seb.sebserver.gbl.api.EntityType; | ||||
| import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; | ||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractExportCall; | ||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractDownloadCall; | ||||
| 
 | ||||
| @Lazy | ||||
| @Component | ||||
| @GuiProfile | ||||
| public class ExportSEBClientLogs extends AbstractExportCall { | ||||
| public class ExportSEBClientLogs extends AbstractDownloadCall { | ||||
| 
 | ||||
|     public ExportSEBClientLogs() { | ||||
|         super(new TypeKey<>( | ||||
|                 CallType.UNDEFINED, | ||||
|                 EntityType.CLIENT_EVENT, | ||||
|                 new TypeReference<InputStream>() { | ||||
|                 }), | ||||
|                 HttpMethod.GET, | ||||
|                 MediaType.APPLICATION_FORM_URLENCODED, | ||||
|         super(MediaType.APPLICATION_FORM_URLENCODED, | ||||
|                 API.SEB_CLIENT_EVENT_ENDPOINT | ||||
|                         + API.SEB_CLIENT_EVENT_EXPORT_PATH_SEGMENT); | ||||
|     } | ||||
|  |  | |||
|  | @ -225,7 +225,7 @@ public class SEBClientEventAdminServiceImpl implements SEBClientEventAdminServic | |||
|         private final String sort; | ||||
| 
 | ||||
|         private int pageNumber = 1; | ||||
|         private final int pageSize = 1000; | ||||
|         private final int pageSize = 10000; | ||||
| 
 | ||||
|         private Collection<ClientEventRecord> nextRecords; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti