1
1
package de .zalando .paradox .nakadi .consumer .core .client .impl ;
2
2
3
+ import static java .lang .String .format ;
4
+
3
5
import static org .assertj .core .api .Assertions .assertThat ;
4
6
import static org .assertj .core .api .Assertions .assertThatThrownBy ;
5
7
10
12
import java .util .List ;
11
13
import java .util .Optional ;
12
14
13
- import org .junit .Ignore ;
15
+ import org .junit .After ;
16
+ import org .junit .Before ;
14
17
import org .junit .Test ;
15
18
16
19
import de .zalando .paradox .nakadi .consumer .core .domain .EventType ;
17
20
import de .zalando .paradox .nakadi .consumer .core .domain .EventTypeCursor ;
18
21
import de .zalando .paradox .nakadi .consumer .core .domain .EventTypePartition ;
19
22
import de .zalando .paradox .nakadi .consumer .core .domain .NakadiPartition ;
23
+ import de .zalando .paradox .nakadi .consumer .core .exceptions .InvalidEventTypeException ;
24
+ import de .zalando .paradox .nakadi .consumer .core .exceptions .UnrecoverableException ;
20
25
import de .zalando .paradox .nakadi .consumer .core .http .handlers .testdomain .OrderReceived ;
21
26
27
+ import okhttp3 .mockwebserver .MockResponse ;
28
+ import okhttp3 .mockwebserver .MockWebServer ;
29
+
22
30
import rx .Single ;
23
31
24
32
public class ClientImplTest {
25
33
26
- private static final String NAKADI_URL = "http://localhost:8080" ;
27
-
28
- private static EventType ORDER_RECEIVED = EventType .of ("order.ORDER_RECEIVED" );
34
+ private static final EventType ORDER_RECEIVED = EventType .of ("order.ORDER_RECEIVED" );
35
+
36
+ private static final String FIRST_ORDER = "ORDER_001" ;
37
+ private static final String SECOND_ORDER = "ORDER_002" ;
38
+
39
+ private static final String WRONG_EVENT_TYPE = "__not_configured__" ;
40
+
41
+ private static final String NAKADI_RESPONSE_PARTITIONS = "[{\" oldest_available_offset\" :\" 000000000000000000\" ,"
42
+ + "\" newest_available_offset\" :\" BEGIN\" ,\" partition\" :\" 0\" }]" ;
43
+ private static final String NAKADI_RESPONSE_ONE_ORDER = "{\" cursor\" :{\" partition\" :\" 0\" ,"
44
+ + "\" offset\" :\" 000000000000000000\" },\" events\" :[{\" metadata\" : "
45
+ + "{\" eid\" : \" 4ae5011e-eb01-11e5-8b4a-1c6f65464fc6\" ,\" occurred_at\" : \" 2016-03-15T23:56:11+01:00\" },"
46
+ + "\" order_number\" : \" " + FIRST_ORDER + "\" }]}" ;
47
+ private static final String NAKADI_RESPONSE_NO_EVENTS_FOUND = "{\" cursor\" :{\" partition\" :\" 0\" ,"
48
+ + "\" offset\" :\" 000000000000000000\" },\" events\" :[]}" ;
49
+ private static final String NAKADI_RESPONSE_NOT_FOUND = "{\" type\" :\" http://httpstatus.es/404\" ,"
50
+ + "\" title\" :\" Not Found\" ,\" status\" :404,\" detail\" :\" topic not found\" }" ;
51
+ private static final String NAKADI_RESPONSE_TWO_ORDERS_ONE_WRONG_TYPE = "{\" cursor\" :{\" partition\" :\" 0\" ,"
52
+ + "\" offset\" :\" 000000000000000000\" },\" events\" :[{\" metadata\" : "
53
+ + "{\" eid\" : \" 4ae5011e-eb01-11e5-8b4a-1c6f65464fc6\" ,\" occurred_at\" : \" 2016-03-15T23:56:11+01:00\" ,"
54
+ + "\" event_type\" : \" " + WRONG_EVENT_TYPE + "\" },\" order_number\" : \" " + FIRST_ORDER + "\" },{\" metadata\" : "
55
+ + "{\" eid\" : \" 4ae5011e-eb01-11e5-8b4a-1c6f65464fc6\" ,\" occurred_at\" : \" 2016-03-15T23:56:11+01:00\" ,"
56
+ + "\" event_type\" : \" " + ORDER_RECEIVED .getName () + "\" },\" order_number\" : \" " + SECOND_ORDER + "\" }]}" ;
57
+
58
+ private MockWebServer mockNakadi ;
59
+
60
+ private static ClientImpl clientImpl ;
61
+
62
+ @ Before
63
+ public void setUp () throws IOException {
64
+ mockNakadi = new MockWebServer ();
65
+ mockNakadi .start (0 );
66
+ clientImpl = ClientImpl .Builder .of (mockNakadi .url ("/" ).toString ()).build ();
67
+ }
29
68
30
- private static ClientImpl clientImpl = ClientImpl .Builder .of (NAKADI_URL ).build ();
69
+ @ After
70
+ public void tearDown () throws IOException {
71
+ mockNakadi .close ();
72
+ }
31
73
32
74
@ Test
33
75
public void testShouldThrowWhenRequestingUnconsumedEventsWithNullCursors () {
34
- assertThatThrownBy (() -> { clientImpl .getCursorsLag (null ); } ).isInstanceOf (NullPointerException .class )
35
- . hasMessage ( "cursors must not be null" );
76
+ assertThatThrownBy (() -> clientImpl .getCursorsLag (null )).isInstanceOf (NullPointerException .class ). hasMessage (
77
+ "cursors must not be null" );
36
78
}
37
79
38
80
@ Test
39
81
public void testShouldThrowWhenRequestingUnconsumedEventsWithEmptyCursors () {
40
- assertThatThrownBy (() -> { clientImpl .getCursorsLag (Collections .emptyList ()); } ).isInstanceOf (
82
+ assertThatThrownBy (() -> clientImpl .getCursorsLag (Collections .emptyList ())).isInstanceOf (
41
83
IllegalArgumentException .class ).hasMessage ("cursors must not be empty" );
42
84
}
43
85
@@ -47,63 +89,81 @@ public void testShouldThrowWhenRequestingUnconsumedEventsForDifferentEventTypes(
47
89
"0" ), "BEGIN" );
48
90
final EventTypeCursor eventTypeCursorDifferentType = EventTypeCursor .of (EventTypePartition .of (
49
91
EventType .of ("test-event-two" ), "0" ), "BEGIN" );
50
- assertThatThrownBy (() -> {
51
- clientImpl .getCursorsLag (
52
- Arrays .asList (eventTypeCursor , eventTypeCursorDifferentType ));
53
- }).isInstanceOf (IllegalArgumentException .class ).hasMessage (
54
- "cursors must contain cursors of only one type" );
92
+ assertThatThrownBy (() ->
93
+ clientImpl .getCursorsLag (
94
+ Arrays .asList (eventTypeCursor , eventTypeCursorDifferentType ))).isInstanceOf (
95
+ IllegalArgumentException .class ).hasMessage ("cursors must contain cursors of only one type" );
55
96
}
56
97
57
98
@ Test
58
- @ Ignore ("Needs Nakadi server" )
59
- public void testGetNakadiPartitionsFound () {
99
+ public void testGetNakadiPartitionsFound () throws IOException {
100
+ mockNakadi .enqueue (new MockResponse ().setBody (NAKADI_RESPONSE_PARTITIONS ));
101
+
60
102
final List <NakadiPartition > list = clientImpl .getPartitions (ORDER_RECEIVED ).toBlocking ().value ();
61
103
assertThat (list ).isNotEmpty ();
62
104
}
63
105
64
106
@ Test
65
- @ Ignore ("Needs Nakadi server" )
66
- public void testGetNakadiPartitionsNotFound () {
67
- final List <NakadiPartition > list = clientImpl .getPartitions (EventType .of ("__not_configured__" ))
107
+ public void testGetNakadiPartitionsNotFound () throws IOException {
108
+ mockNakadi .enqueue (new MockResponse ().setResponseCode (404 ).setBody (NAKADI_RESPONSE_NOT_FOUND ));
109
+
110
+ final List <NakadiPartition > list = clientImpl .getPartitions (EventType .of (WRONG_EVENT_TYPE ))
68
111
.onErrorReturn (throwable -> Collections .emptyList ()).toBlocking ()
69
112
.value ();
70
113
assertThat (list ).isEmpty ();
71
114
}
72
115
73
116
@ Test
74
- @ Ignore ("Needs Nakadi server" )
75
- public void testGetNakadiEventPayload () {
117
+ public void testGetNakadiEventPayload () throws IOException {
118
+ mockNakadi .enqueue (new MockResponse ().setBody (NAKADI_RESPONSE_ONE_ORDER ));
119
+
76
120
final EventTypeCursor cursor = EventTypeCursor .of (EventTypePartition .of (ORDER_RECEIVED , "0" ), "0" );
77
121
final String event = clientImpl .getEvent (cursor ).toBlocking ().value ();
78
122
assertThat (event ).startsWith ("{\" metadata\" :{" );
79
123
assertThat (event ).contains ("\" order_number\" " );
80
124
}
81
125
82
126
@ Test
83
- @ Ignore ("Needs Nakadi server" )
84
- public void testGetNakadiEventStream () {
127
+ public void testGetNakadiEventStream () throws IOException {
128
+ mockNakadi .enqueue (new MockResponse ().setBody (NAKADI_RESPONSE_ONE_ORDER ));
129
+
85
130
final EventTypeCursor cursor = EventTypeCursor .of (EventTypePartition .of (ORDER_RECEIVED , "0" ), "BEGIN" );
86
131
final String stream = clientImpl .getContent (cursor ).toBlocking ().value ();
87
- assertThat (stream ).startsWith ("{\" cursor\" :{\" partition\" :\" 0\" ,\" offset\" :\" 0 \" }" );
132
+ assertThat (stream ).startsWith ("{\" cursor\" :{\" partition\" :\" 0\" ,\" offset\" :\" 000000000000000000 \" }" );
88
133
assertThat (stream ).contains ("\" order_number\" " );
89
134
}
90
135
91
136
@ Test
92
- @ Ignore ("Needs Nakadi server" )
93
- public void testGetNakadiEventObject () {
137
+ public void testGetNakadiEventObject () throws IOException {
138
+ mockNakadi .enqueue (new MockResponse ().setBody (NAKADI_RESPONSE_ONE_ORDER ));
139
+
94
140
final EventTypeCursor cursor = EventTypeCursor .of (EventTypePartition .of (ORDER_RECEIVED , "0" ), "0" );
95
141
final OrderReceived event = getEvent (cursor , OrderReceived .class ).toBlocking ().value ();
96
142
assertThat (event .getOrderNumber ()).isNotEmpty ();
97
143
}
98
144
99
145
@ Test
100
- @ Ignore ("Needs Nakadi server" )
101
- public void testGetNakadiEventNotFound () {
102
- final EventTypeCursor cursor = EventTypeCursor .of (EventTypePartition .of (ORDER_RECEIVED , "0" ), "100000" );
146
+ public void testGetNakadiEventNotFound () throws IOException {
147
+ mockNakadi .enqueue (new MockResponse ().setBody (NAKADI_RESPONSE_NO_EVENTS_FOUND ));
148
+
149
+ final EventTypeCursor cursor = EventTypeCursor .of (EventTypePartition .of (ORDER_RECEIVED , "0" ),
150
+ "00000000000100000" );
103
151
final String event = clientImpl .getEvent (cursor ).onErrorReturn (throwable -> null ).toBlocking ().value ();
104
152
assertThat (event ).isNull ();
105
153
}
106
154
155
+ @ Test
156
+ public void testShouldStopProcessingAndThrowUnrecoverableExceptionWhenItReceivesWrongEventTypes ()
157
+ throws IOException {
158
+ mockNakadi .enqueue (new MockResponse ().setBody (NAKADI_RESPONSE_TWO_ORDERS_ONE_WRONG_TYPE ));
159
+
160
+ final EventTypeCursor cursor = EventTypeCursor .of (EventTypePartition .of (ORDER_RECEIVED , "0" ), "0" );
161
+ assertThatThrownBy (() -> getEvent (cursor , OrderReceived .class ).toBlocking ().value ()).isInstanceOf (
162
+ InvalidEventTypeException .class ).isInstanceOf (UnrecoverableException .class )
163
+ .hasMessage (format ("Unexpected event type (expected=[%s], actual=[%s])" ,
164
+ ORDER_RECEIVED .getName (), WRONG_EVENT_TYPE ));
165
+ }
166
+
107
167
private <T > Single <T > getEvent (final EventTypeCursor cursor , final Class <T > clazz ) {
108
168
return clientImpl .getEvent (cursor ).map (content -> getEvent0 (content , clazz )).map (o -> o .orElse (null ));
109
169
}
0 commit comments