// private void multiThreadedMarshal(PrintWriter writer, List<Result> results, private String multiThreadedMarshal( List<Result> results, String recordSchema, final Map<String, Serializable> arguments) throws CatalogTransformerException { CompletionService<BinaryContent> completionService = new ExecutorCompletionService<>(queryExecutor); try { final MetacardTransformer transformer = metacardTransformerManager.getTransformerBySchema(recordSchema); if (transformer == null) { throw new CatalogTransformerException( "Cannot find transformer for schema: " + recordSchema); } Map<Future<BinaryContent>, Result> futures = new HashMap<>(results.size()); for (Result result : results) { final Metacard mc = result.getMetacard(); // the "current" thread will run submitted task when queueSize exceeded; effectively // blocking enqueue of more tasks. futures.put( completionService.submit( () -> { BinaryContent content = transformer.transform(mc, arguments); return content; }), result); } // TODO - really? I can't use a list of some sort? InputStream[] contents = new InputStream[results.size()]; while (!futures.isEmpty()) { Future<BinaryContent> completedFuture = completionService.take(); int index = results.indexOf(futures.get(completedFuture)); contents[index] = completedFuture.get().getInputStream(); futures.remove(completedFuture); } CharArrayWriter accum = new CharArrayWriter(ACCUM_INITIAL_SIZE); for (InputStream is : contents) { IOUtils.copy(is, accum); } return accum.toString(); } catch (IOException | InterruptedException | ExecutionException xe) { throw new CatalogTransformerException(xe); } } // end multiThreadedMarshal()
@Before public void setUp() throws Exception { System.setProperty("ddf.home", "."); callbackURI = new URL("https://localhost:12345/services/csw/subscription/event"); ObjectFactory objectFactory = new ObjectFactory(); request = new GetRecordsType(); request.setOutputSchema(CswConstants.CSW_OUTPUT_SCHEMA); request.setResultType(ResultType.RESULTS); request.getResponseHandler().add(callbackURI.toString()); queryType = new QueryType(); elementSetNameType = new ElementSetNameType(); elementSetNameType.setValue(ElementSetType.BRIEF); queryType.setElementSetName(elementSetNameType); request.setAbstractQuery(objectFactory.createAbstractQuery(queryType)); transformerManager = mock(TransformerManager.class); transformer = mock(QueryResponseTransformer.class); binaryContent = mock(BinaryContent.class); when(transformerManager.getTransformerBySchema( Matchers.contains(CswConstants.CSW_OUTPUT_SCHEMA))) .thenReturn(transformer); when(transformer.transform(any(SourceResponse.class), anyMap())).thenReturn(binaryContent); when(binaryContent.getByteArray()).thenReturn("byte array with message contents".getBytes()); query = mock(QueryRequest.class); metacard = mock(Metacard.class); webclient = mock(WebClient.class); mockCxfClientFactory = mock(SecureCxfClientFactory.class); response = mock(Response.class); subject = mock(Subject.class); mockSecurity = mock(Security.class); headers.put(Subject.class.toString(), Arrays.asList(new Subject[] {subject})); AccessPlugin accessPlugin = mock(AccessPlugin.class); accessPlugins.add(accessPlugin); when(mockCxfClientFactory.getWebClient()).thenReturn(webclient); // when(webclient.head()).thenReturn(response); when(webclient.invoke(anyString(), any(QueryResponse.class))).thenReturn(response); when(response.getHeaders()).thenReturn(headers); when(accessPlugin.processPostQuery(any(QueryResponse.class))) .thenAnswer( new Answer<QueryResponse>() { @Override public QueryResponse answer(InvocationOnMock invocationOnMock) throws Throwable { return (QueryResponse) invocationOnMock.getArguments()[0]; } }); sendEvent = new SendEventExtension(transformerManager, request, query, mockCxfClientFactory); sendEvent.setSubject(subject); }