1
+ package org .dataloader .instrumentation ;
2
+
3
+ import org .dataloader .BatchLoaderEnvironment ;
4
+ import org .dataloader .DataLoader ;
5
+ import org .dataloader .DataLoaderFactory ;
6
+ import org .dataloader .DataLoaderOptions ;
7
+ import org .dataloader .DispatchResult ;
8
+ import org .dataloader .fixtures .TestKit ;
9
+ import org .dataloader .fixtures .parameterized .TestDataLoaderFactory ;
10
+ import org .junit .jupiter .api .Test ;
11
+ import org .junit .jupiter .params .ParameterizedTest ;
12
+ import org .junit .jupiter .params .provider .MethodSource ;
13
+
14
+ import java .util .ArrayList ;
15
+ import java .util .List ;
16
+ import java .util .concurrent .CompletableFuture ;
17
+
18
+ import static org .awaitility .Awaitility .await ;
19
+ import static org .dataloader .DataLoaderOptions .newOptions ;
20
+ import static org .hamcrest .MatcherAssert .assertThat ;
21
+ import static org .hamcrest .Matchers .equalTo ;
22
+
23
+ class ChainedDataLoaderInstrumentationTest {
24
+
25
+ static class CapturingInstrumentation implements DataLoaderInstrumentation {
26
+ String name ;
27
+ List <String > methods = new ArrayList <>();
28
+
29
+ public CapturingInstrumentation (String name ) {
30
+ this .name = name ;
31
+ }
32
+
33
+ @ Override
34
+ public DataLoaderInstrumentationContext <DispatchResult <?>> beginDispatch (DataLoader <?, ?> dataLoader ) {
35
+ methods .add (name + "_beginDispatch" );
36
+ return new DataLoaderInstrumentationContext <>() {
37
+ @ Override
38
+ public void onDispatched () {
39
+ methods .add (name + "_beginDispatch_onDispatched" );
40
+ }
41
+
42
+ @ Override
43
+ public void onCompleted (DispatchResult <?> result , Throwable t ) {
44
+ methods .add (name + "_beginDispatch_onCompleted" );
45
+ }
46
+ };
47
+ }
48
+
49
+ @ Override
50
+ public DataLoaderInstrumentationContext <List <?>> beginBatchLoader (DataLoader <?, ?> dataLoader , List <?> keys , BatchLoaderEnvironment environment ) {
51
+ methods .add (name + "_beginBatchLoader" );
52
+ return new DataLoaderInstrumentationContext <>() {
53
+ @ Override
54
+ public void onDispatched () {
55
+ methods .add (name + "_beginBatchLoader_onDispatched" );
56
+ }
57
+
58
+ @ Override
59
+ public void onCompleted (List <?> result , Throwable t ) {
60
+ methods .add (name + "_beginBatchLoader_onCompleted" );
61
+ }
62
+ };
63
+ }
64
+ }
65
+
66
+
67
+ static class CapturingInstrumentationReturnsNull extends CapturingInstrumentation {
68
+
69
+ public CapturingInstrumentationReturnsNull (String name ) {
70
+ super (name );
71
+ }
72
+
73
+ @ Override
74
+ public DataLoaderInstrumentationContext <DispatchResult <?>> beginDispatch (DataLoader <?, ?> dataLoader ) {
75
+ methods .add (name + "_beginDispatch" );
76
+ return null ;
77
+ }
78
+
79
+ @ Override
80
+ public DataLoaderInstrumentationContext <List <?>> beginBatchLoader (DataLoader <?, ?> dataLoader , List <?> keys , BatchLoaderEnvironment environment ) {
81
+ methods .add (name + "_beginBatchLoader" );
82
+ return null ;
83
+ }
84
+ }
85
+
86
+ @ Test
87
+ void canChainTogetherZeroInstrumentation () {
88
+ // just to prove its useless but harmless
89
+ ChainedDataLoaderInstrumentation chainedItn = new ChainedDataLoaderInstrumentation ();
90
+
91
+ DataLoaderOptions options = newOptions ().setInstrumentation (chainedItn );
92
+
93
+ DataLoader <String , String > dl = DataLoaderFactory .newDataLoader (TestKit .keysAsValues (), options );
94
+
95
+ dl .load ("A" );
96
+ dl .load ("B" );
97
+
98
+ CompletableFuture <List <String >> dispatch = dl .dispatch ();
99
+
100
+ await ().until (dispatch ::isDone );
101
+ assertThat (dispatch .join (), equalTo (List .of ("A" , "B" )));
102
+ }
103
+
104
+ @ Test
105
+ void canChainTogetherOneInstrumentation () {
106
+ CapturingInstrumentation capturingA = new CapturingInstrumentation ("A" );
107
+
108
+ ChainedDataLoaderInstrumentation chainedItn = new ChainedDataLoaderInstrumentation ()
109
+ .add (capturingA );
110
+
111
+ DataLoaderOptions options = newOptions ().setInstrumentation (chainedItn );
112
+
113
+ DataLoader <String , String > dl = DataLoaderFactory .newDataLoader (TestKit .keysAsValues (), options );
114
+
115
+ dl .load ("A" );
116
+ dl .load ("B" );
117
+
118
+ CompletableFuture <List <String >> dispatch = dl .dispatch ();
119
+
120
+ await ().until (dispatch ::isDone );
121
+
122
+ assertThat (capturingA .methods , equalTo (List .of ("A_beginDispatch" ,
123
+ "A_beginBatchLoader" , "A_beginBatchLoader_onDispatched" , "A_beginBatchLoader_onCompleted" ,
124
+ "A_beginDispatch_onDispatched" , "A_beginDispatch_onCompleted" )));
125
+ }
126
+
127
+
128
+ @ ParameterizedTest
129
+ @ MethodSource ("org.dataloader.fixtures.parameterized.TestDataLoaderFactories#get" )
130
+ public void canChainTogetherManyInstrumentationsWithDifferentBatchLoaders (TestDataLoaderFactory factory ) {
131
+ CapturingInstrumentation capturingA = new CapturingInstrumentation ("A" );
132
+ CapturingInstrumentation capturingB = new CapturingInstrumentation ("B" );
133
+ CapturingInstrumentation capturingButReturnsNull = new CapturingInstrumentationReturnsNull ("NULL" );
134
+
135
+ ChainedDataLoaderInstrumentation chainedItn = new ChainedDataLoaderInstrumentation ()
136
+ .add (capturingA )
137
+ .add (capturingB )
138
+ .add (capturingButReturnsNull );
139
+
140
+ DataLoaderOptions options = newOptions ().setInstrumentation (chainedItn );
141
+
142
+ DataLoader <String , String > dl = factory .idLoader (options );
143
+
144
+ dl .load ("A" );
145
+ dl .load ("B" );
146
+
147
+ CompletableFuture <List <String >> dispatch = dl .dispatch ();
148
+
149
+ await ().until (dispatch ::isDone );
150
+
151
+ //
152
+ // A_beginBatchLoader happens before A_beginDispatch_onDispatched because these are sync
153
+ // and no async - a batch scheduler or async batch loader would change that
154
+ //
155
+ assertThat (capturingA .methods , equalTo (List .of ("A_beginDispatch" ,
156
+ "A_beginBatchLoader" , "A_beginBatchLoader_onDispatched" , "A_beginBatchLoader_onCompleted" ,
157
+ "A_beginDispatch_onDispatched" , "A_beginDispatch_onCompleted" )));
158
+
159
+ assertThat (capturingB .methods , equalTo (List .of ("B_beginDispatch" ,
160
+ "B_beginBatchLoader" , "B_beginBatchLoader_onDispatched" , "B_beginBatchLoader_onCompleted" ,
161
+ "B_beginDispatch_onDispatched" , "B_beginDispatch_onCompleted" )));
162
+
163
+ // it returned null on all its contexts - nothing to call back on
164
+ assertThat (capturingButReturnsNull .methods , equalTo (List .of ("NULL_beginDispatch" , "NULL_beginBatchLoader" )));
165
+ }
166
+ }
0 commit comments