28
28
import java .io .ByteArrayInputStream ;
29
29
import java .io .IOException ;
30
30
import java .io .InputStream ;
31
+ import java .io .UncheckedIOException ;
31
32
import java .util .ArrayList ;
32
33
import java .util .Collection ;
33
34
import java .util .Comparator ;
34
35
import java .util .List ;
36
+ import java .util .concurrent .BlockingQueue ;
37
+ import java .util .concurrent .ConcurrentHashMap ;
35
38
36
39
import org .junit .Test ;
37
40
40
43
import org .springframework .integration .StaticMessageHeaderAccessor ;
41
44
import org .springframework .integration .channel .QueueChannel ;
42
45
import org .springframework .integration .file .FileHeaders ;
46
+ import org .springframework .integration .file .filters .AbstractPersistentAcceptOnceFileListFilter ;
43
47
import org .springframework .integration .file .filters .AcceptOnceFileListFilter ;
44
48
import org .springframework .integration .file .remote .session .Session ;
45
49
import org .springframework .integration .file .remote .session .SessionFactory ;
46
50
import org .springframework .integration .file .splitter .FileSplitter ;
51
+ import org .springframework .integration .metadata .ConcurrentMetadataStore ;
52
+ import org .springframework .integration .metadata .SimpleMetadataStore ;
53
+ import org .springframework .integration .test .util .TestUtils ;
47
54
import org .springframework .integration .transformer .StreamTransformer ;
48
55
import org .springframework .messaging .Message ;
49
- import org .springframework .messaging .MessagingException ;
50
56
51
57
/**
52
58
* @author Gary Russell
@@ -67,6 +73,7 @@ public void testAllData() throws Exception {
67
73
streamer .setBeanFactory (mock (BeanFactory .class ));
68
74
streamer .setRemoteDirectory ("/foo" );
69
75
streamer .afterPropertiesSet ();
76
+ streamer .start ();
70
77
Message <byte []> received = (Message <byte []>) this .transformer .transform (streamer .receive ());
71
78
assertThat (received .getPayload ()).isEqualTo ("foo\n bar" .getBytes ());
72
79
assertThat (received .getHeaders ().get (FileHeaders .REMOTE_DIRECTORY )).isEqualTo ("/foo" );
@@ -112,6 +119,7 @@ public void testAllDataMaxFetch() throws Exception {
112
119
streamer .setMaxFetchSize (1 );
113
120
streamer .setFilter (new AcceptOnceFileListFilter <>());
114
121
streamer .afterPropertiesSet ();
122
+ streamer .start ();
115
123
Message <byte []> received = (Message <byte []>) this .transformer .transform (streamer .receive ());
116
124
assertThat (received .getPayload ()).isEqualTo ("foo\n bar" .getBytes ());
117
125
assertThat (received .getHeaders ().get (FileHeaders .REMOTE_DIRECTORY )).isEqualTo ("/foo" );
@@ -138,17 +146,18 @@ public void testExceptionOnFetch() {
138
146
streamer .setBeanFactory (mock (BeanFactory .class ));
139
147
streamer .setRemoteDirectory ("/bad" );
140
148
streamer .afterPropertiesSet ();
141
- assertThatExceptionOfType (MessagingException .class )
149
+ streamer .start ();
150
+ assertThatExceptionOfType (UncheckedIOException .class )
142
151
.isThrownBy (streamer ::receive );
143
152
}
144
153
145
- @ SuppressWarnings ("unchecked" )
146
154
@ Test
147
155
public void testLineByLine () throws Exception {
148
156
Streamer streamer = new Streamer (new StringRemoteFileTemplate (new StringSessionFactory ()), null );
149
157
streamer .setBeanFactory (mock (BeanFactory .class ));
150
158
streamer .setRemoteDirectory ("/foo" );
151
159
streamer .afterPropertiesSet ();
160
+ streamer .start ();
152
161
QueueChannel out = new QueueChannel ();
153
162
FileSplitter splitter = new FileSplitter ();
154
163
splitter .setBeanFactory (mock (BeanFactory .class ));
@@ -160,7 +169,7 @@ public void testLineByLine() throws Exception {
160
169
assertThat (received .getPayload ()).isEqualTo ("foo" );
161
170
assertThat (received .getHeaders ().get (FileHeaders .REMOTE_DIRECTORY )).isEqualTo ("/foo" );
162
171
assertThat (received .getHeaders ().get (FileHeaders .REMOTE_FILE )).isEqualTo ("foo" );
163
- received = ( Message < byte []>) out .receive (0 );
172
+ received = out .receive (0 );
164
173
assertThat (received .getPayload ()).isEqualTo ("bar" );
165
174
assertThat (received .getHeaders ().get (FileHeaders .REMOTE_DIRECTORY )).isEqualTo ("/foo" );
166
175
assertThat (received .getHeaders ().get (FileHeaders .REMOTE_FILE )).isEqualTo ("foo" );
@@ -185,10 +194,43 @@ public void testLineByLine() throws Exception {
185
194
verify (new IntegrationMessageHeaderAccessor (receivedStream ).getCloseableResource (), times (5 )).close ();
186
195
}
187
196
197
+ @ SuppressWarnings ("unchecked" )
198
+ @ Test
199
+ public void testStopAdapterRemovesUnprocessed () {
200
+ Streamer streamer = new Streamer (new StringRemoteFileTemplate (new StringSessionFactory ()), null );
201
+ streamer .setBeanFactory (mock (BeanFactory .class ));
202
+ streamer .setRemoteDirectory ("/foo" );
203
+ streamer .afterPropertiesSet ();
204
+ streamer .start ();
205
+ assertThat (streamer .receive ()).isNotNull ();
206
+ assertThat (TestUtils .getPropertyValue (streamer , "toBeReceived" , BlockingQueue .class )).hasSize (1 );
207
+ assertThat (streamer .metadataMap ).hasSize (2 );
208
+ streamer .stop ();
209
+ assertThat (TestUtils .getPropertyValue (streamer , "toBeReceived" , BlockingQueue .class )).hasSize (0 );
210
+ assertThat (streamer .metadataMap ).hasSize (1 );
211
+ }
212
+
213
+ @ SuppressWarnings ("unchecked" )
214
+ @ Test
215
+ public void testFilterReversedOnBadFetch () {
216
+ Streamer streamer = new Streamer (new StringRemoteFileTemplate (new StringSessionFactory ()), null );
217
+ streamer .setBeanFactory (mock (BeanFactory .class ));
218
+ streamer .setRemoteDirectory ("/bad" );
219
+ streamer .afterPropertiesSet ();
220
+ streamer .start ();
221
+ assertThatExceptionOfType (UncheckedIOException .class )
222
+ .isThrownBy (streamer ::receive );
223
+ assertThat (TestUtils .getPropertyValue (streamer , "toBeReceived" , BlockingQueue .class )).hasSize (1 );
224
+ assertThat (streamer .metadataMap ).hasSize (1 );
225
+ }
226
+
188
227
public static class Streamer extends AbstractRemoteFileStreamingMessageSource <String > {
189
228
229
+ ConcurrentHashMap <String , String > metadataMap = new ConcurrentHashMap <>();
230
+
190
231
protected Streamer (RemoteFileTemplate <String > template , Comparator <String > comparator ) {
191
232
super (template , comparator );
233
+ doSetFilter (new StringPersistentFileListFilter (new SimpleMetadataStore (this .metadataMap ), "streamer" ));
192
234
}
193
235
194
236
@ Override
@@ -252,11 +294,7 @@ public String getPermissions() {
252
294
253
295
@ Override
254
296
public String getFileInfo () {
255
- return asString ();
256
- }
257
-
258
- private String asString () {
259
- return "StringFileInfo [name=" + this .name + "]" ;
297
+ return name ;
260
298
}
261
299
262
300
}
@@ -271,13 +309,13 @@ public StringRemoteFileTemplate(SessionFactory<String> sessionFactory) {
271
309
272
310
public static class StringSessionFactory implements SessionFactory <String > {
273
311
274
- private Session <String > session ;
312
+ private Session <String > singletonSession ;
275
313
276
314
@ SuppressWarnings ("unchecked" )
277
315
@ Override
278
316
public Session <String > getSession () {
279
- if (this .session != null ) {
280
- return this .session ;
317
+ if (this .singletonSession != null ) {
318
+ return this .singletonSession ;
281
319
}
282
320
try {
283
321
Session <String > session = mock (Session .class );
@@ -293,12 +331,13 @@ public Session<String> getSession() {
293
331
willReturn (foo2 ).given (session ).readRaw ("/bar/foo" );
294
332
willReturn (bar2 ).given (session ).readRaw ("/bar/bar" );
295
333
296
- willReturn (new String [] { "/bad/file" }).given (session ).list ("/bad" );
297
- willThrow (new IOException ("No file" )).given (session ).readRaw ("/bad/file" );
334
+ willReturn (new String [] { "/bad/file1" , "/bad/file2" }).given (session ).list ("/bad" );
335
+ willThrow (new IOException ("No file" )).given (session ).readRaw ("/bad/file1" );
336
+ willThrow (new IOException ("No file" )).given (session ).readRaw ("/bad/file2" );
298
337
299
338
given (session .finalizeRaw ()).willReturn (true );
300
339
301
- this .session = session ;
340
+ this .singletonSession = session ;
302
341
303
342
return session ;
304
343
}
@@ -309,4 +348,22 @@ public Session<String> getSession() {
309
348
310
349
}
311
350
351
+ public static class StringPersistentFileListFilter extends AbstractPersistentAcceptOnceFileListFilter <String > {
352
+
353
+ public StringPersistentFileListFilter (ConcurrentMetadataStore store , String prefix ) {
354
+ super (store , prefix );
355
+ }
356
+
357
+ @ Override
358
+ protected long modified (String file ) {
359
+ return 0 ;
360
+ }
361
+
362
+ @ Override
363
+ protected String fileName (String file ) {
364
+ return file ;
365
+ }
366
+
367
+ }
368
+
312
369
}
0 commit comments