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,13 +55,12 @@ public class SEBClientLogExport extends AbstractDownloadServiceHandler { | ||||||
|             queryParams.add(param, String.valueOf(request.getParameter(param))); |             queryParams.add(param, String.valueOf(request.getParameter(param))); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         final InputStream input = this.restService |         this.restService | ||||||
|                 .getBuilder(ExportSEBClientLogs.class) |                 .getBuilder(ExportSEBClientLogs.class) | ||||||
|                 .withQueryParams(queryParams) |                 .withResponseExtractor(response -> { | ||||||
|                 .call() |  | ||||||
|                 .getOrThrow(); |  | ||||||
| 
 | 
 | ||||||
|                     try { |                     try { | ||||||
|  |                         final InputStream input = response.getBody(); | ||||||
|                         IOUtils.copyLarge(input, downloadOut); |                         IOUtils.copyLarge(input, downloadOut); | ||||||
|                     } catch (final IOException e) { |                     } catch (final IOException e) { | ||||||
|                         log.error( |                         log.error( | ||||||
|  | @ -75,6 +74,13 @@ public class SEBClientLogExport extends AbstractDownloadServiceHandler { | ||||||
|                             log.error("Unexpected error while trying to close download output-stream"); |                             log.error("Unexpected error while trying to close download output-stream"); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | 
 | ||||||
|  |                     return true; | ||||||
|  |                 }) | ||||||
|  |                 .withQueryParams(queryParams) | ||||||
|  |                 .call() | ||||||
|  |                 .onError(error -> log.error("Download failed: ", error)); | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | 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> { | public abstract class AbstractExportCall extends RestCall<InputStream> { | ||||||
| 
 | 
 | ||||||
|     protected AbstractExportCall( |     protected AbstractExportCall( | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ import org.springframework.http.ResponseEntity; | ||||||
| import org.springframework.util.LinkedMultiValueMap; | import org.springframework.util.LinkedMultiValueMap; | ||||||
| import org.springframework.util.MultiValueMap; | import org.springframework.util.MultiValueMap; | ||||||
| import org.springframework.web.client.ResourceAccessException; | import org.springframework.web.client.ResourceAccessException; | ||||||
|  | import org.springframework.web.client.ResponseExtractor; | ||||||
| import org.springframework.web.client.RestClientResponseException; | import org.springframework.web.client.RestClientResponseException; | ||||||
| import org.springframework.web.client.RestTemplate; | import org.springframework.web.client.RestTemplate; | ||||||
| import org.springframework.web.util.UriComponentsBuilder; | import org.springframework.web.util.UriComponentsBuilder; | ||||||
|  | @ -224,6 +225,7 @@ public abstract class RestCall<T> { | ||||||
|         private final HttpHeaders httpHeaders; |         private final HttpHeaders httpHeaders; | ||||||
|         private String body = null; |         private String body = null; | ||||||
|         private InputStream streamingBody = null; |         private InputStream streamingBody = null; | ||||||
|  |         private ResponseExtractor<Boolean> responseExtractor = null; | ||||||
| 
 | 
 | ||||||
|         private final MultiValueMap<String, String> queryParams; |         private final MultiValueMap<String, String> queryParams; | ||||||
|         private final Map<String, String> uriVariables; |         private final Map<String, String> uriVariables; | ||||||
|  | @ -253,6 +255,15 @@ public abstract class RestCall<T> { | ||||||
|             return this.restTemplate; |             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) { |         public RestCallBuilder withRestTemplate(final RestTemplate restTemplate) { | ||||||
|             this.restTemplate = restTemplate; |             this.restTemplate = restTemplate; | ||||||
|             return this; |             return this; | ||||||
|  |  | ||||||
|  | @ -8,33 +8,21 @@ | ||||||
| 
 | 
 | ||||||
| package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam; | package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam; | ||||||
| 
 | 
 | ||||||
| import java.io.InputStream; |  | ||||||
| 
 |  | ||||||
| import org.springframework.context.annotation.Lazy; | import org.springframework.context.annotation.Lazy; | ||||||
| import org.springframework.http.HttpMethod; |  | ||||||
| import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||||
| import org.springframework.stereotype.Component; | 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.API; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.EntityType; |  | ||||||
| import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; | 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 | @Lazy | ||||||
| @Component | @Component | ||||||
| @GuiProfile | @GuiProfile | ||||||
| public class ExportSEBClientLogs extends AbstractExportCall { | public class ExportSEBClientLogs extends AbstractDownloadCall { | ||||||
| 
 | 
 | ||||||
|     public ExportSEBClientLogs() { |     public ExportSEBClientLogs() { | ||||||
|         super(new TypeKey<>( |         super(MediaType.APPLICATION_FORM_URLENCODED, | ||||||
|                 CallType.UNDEFINED, |  | ||||||
|                 EntityType.CLIENT_EVENT, |  | ||||||
|                 new TypeReference<InputStream>() { |  | ||||||
|                 }), |  | ||||||
|                 HttpMethod.GET, |  | ||||||
|                 MediaType.APPLICATION_FORM_URLENCODED, |  | ||||||
|                 API.SEB_CLIENT_EVENT_ENDPOINT |                 API.SEB_CLIENT_EVENT_ENDPOINT | ||||||
|                         + API.SEB_CLIENT_EVENT_EXPORT_PATH_SEGMENT); |                         + API.SEB_CLIENT_EVENT_EXPORT_PATH_SEGMENT); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -225,7 +225,7 @@ public class SEBClientEventAdminServiceImpl implements SEBClientEventAdminServic | ||||||
|         private final String sort; |         private final String sort; | ||||||
| 
 | 
 | ||||||
|         private int pageNumber = 1; |         private int pageNumber = 1; | ||||||
|         private final int pageSize = 1000; |         private final int pageSize = 10000; | ||||||
| 
 | 
 | ||||||
|         private Collection<ClientEventRecord> nextRecords; |         private Collection<ClientEventRecord> nextRecords; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti