Skip to content

Commit d035ed2

Browse files
committed
parsing ss events
1 parent 4a91a22 commit d035ed2

File tree

6 files changed

+427
-33
lines changed

6 files changed

+427
-33
lines changed

unirest-bdd-tests/src/test/java/BehaviorTests/SSETest.java

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,9 @@
2626
package BehaviorTests;
2727

2828

29-
import kong.unirest.core.SseListener;
3029
import kong.unirest.core.Unirest;
3130
import org.junit.jupiter.api.Test;
3231

33-
import java.util.ArrayList;
34-
import java.util.Collections;
35-
import java.util.List;
36-
import java.util.stream.Stream;
37-
3832
import static org.assertj.core.api.Assertions.assertThat;
3933
import static org.junit.jupiter.api.Assertions.assertTrue;
4034

@@ -57,28 +51,9 @@ void basicConnection() throws Exception {
5751

5852
Thread.sleep(1000);
5953

60-
tl.assertHasComment(": hey1");
61-
tl.assertHasComment(": hey2");
62-
63-
}
64-
65-
public class TestListener implements SseListener {
66-
private final List<String> comments = Collections.synchronizedList(new ArrayList<>());
67-
68-
void assertHasComment(String comment){
69-
assertThat(comments)
70-
.contains(comment);
71-
}
72-
73-
@Override
74-
public void onEvent(String name, String data) {
75-
76-
}
54+
tl.assertHasComment("hey1");
55+
tl.assertHasComment("hey2");
7756

78-
@Override
79-
public void onComment(String line) {
80-
comments.add(line);
81-
}
8257
}
8358

8459
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* The MIT License
3+
*
4+
* Copyright for portions of unirest-java are held by Kong Inc (c) 2013.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining
7+
* a copy of this software and associated documentation files (the
8+
* "Software"), to deal in the Software without restriction, including
9+
* without limitation the rights to use, copy, modify, merge, publish,
10+
* distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to
12+
* the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be
15+
* included in all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
package BehaviorTests;
27+
28+
import kong.unirest.core.SseListener;
29+
import kong.unirest.core.java.SseEvent;
30+
31+
import java.util.ArrayList;
32+
import java.util.Collections;
33+
import java.util.List;
34+
35+
import static org.assertj.core.api.Assertions.assertThat;
36+
37+
public class TestListener implements SseListener {
38+
private final List<String> comments = Collections.synchronizedList(new ArrayList<>());
39+
40+
void assertHasComment(String comment) {
41+
assertThat(comments)
42+
.contains(comment);
43+
}
44+
45+
46+
@Override
47+
public void onEvent(SseEvent event) {
48+
49+
}
50+
51+
@Override
52+
public void onComment(String line) {
53+
comments.add(line);
54+
}
55+
}

unirest/src/main/java/kong/unirest/core/SseListener.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525

2626
package kong.unirest.core;
2727

28+
import kong.unirest.core.java.SseEvent;
29+
2830
public interface SseListener {
29-
void onEvent(String name, String data);
31+
void onEvent(SseEvent event);
3032
void onComment(String line);
3133
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* The MIT License
3+
*
4+
* Copyright for portions of unirest-java are held by Kong Inc (c) 2013.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining
7+
* a copy of this software and associated documentation files (the
8+
* "Software"), to deal in the Software without restriction, including
9+
* without limitation the rights to use, copy, modify, merge, publish,
10+
* distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to
12+
* the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be
15+
* included in all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
package kong.unirest.core.java;
27+
28+
import java.util.Objects;
29+
30+
public class SseEvent {
31+
private final String id;
32+
private final Object data;
33+
private final String name;
34+
35+
public SseEvent(String id, String type, Object data){
36+
this.id = id;
37+
this.name = type;
38+
this.data = data;
39+
}
40+
41+
public Object data() {
42+
return data;
43+
}
44+
45+
public String id() {
46+
return id;
47+
}
48+
49+
public String name() {
50+
return name;
51+
}
52+
53+
@Override
54+
public boolean equals(Object o) {
55+
if (!(o instanceof SseEvent)) return false;
56+
SseEvent sseEvent = (SseEvent) o;
57+
return Objects.equals(id, sseEvent.id)
58+
&& Objects.equals(data, sseEvent.data)
59+
&& Objects.equals(name, sseEvent.name);
60+
}
61+
62+
@Override
63+
public int hashCode() {
64+
return Objects.hash(id, data);
65+
}
66+
67+
@Override
68+
public String toString() {
69+
return "SseEvent{" +
70+
"id='" + id + '\'' +
71+
", data=" + data +
72+
", name=" + name +
73+
'}';
74+
}
75+
}
Lines changed: 139 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
/**
2+
* The MIT License
3+
*
4+
* Copyright for portions of unirest-java are held by Kong Inc (c) 2013.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining
7+
* a copy of this software and associated documentation files (the
8+
* "Software"), to deal in the Software without restriction, including
9+
* without limitation the rights to use, copy, modify, merge, publish,
10+
* distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to
12+
* the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be
15+
* included in all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
126
package kong.unirest.core.java;
227

328
import kong.unirest.core.SseListener;
@@ -8,17 +33,126 @@
833

934
class SseResponseHandler implements Consumer<HttpResponse<Stream<String>>> {
1035
private final SseListener listener;
36+
private EventBuffer databuffer = new EventBuffer();
1137

1238
public SseResponseHandler(SseListener listener) {
1339
this.listener = listener;
1440
}
1541

1642
@Override
1743
public void accept(HttpResponse<Stream<String>> response) {
18-
response.body().forEach(line -> {
19-
if (!line.isBlank()) {
20-
listener.onComment(line);
21-
}
22-
});
44+
response.body().forEach(this::accept);
45+
}
46+
47+
private void accept(String line) {
48+
var pl = parse(line);
49+
50+
if(pl.isDispatch()){
51+
listener.onEvent(databuffer.toEvent());
52+
databuffer = new EventBuffer();
53+
} else if (pl.isComment()) {
54+
listener.onComment(pl.value());
55+
} else if(pl.isData()) {
56+
databuffer.buffer.append(pl.value()).append("\n");
57+
} else if(pl.isEvent()){
58+
databuffer.type = pl.value();
59+
} else if (pl.isId()){
60+
databuffer.id = pl.value();
61+
} else if (pl.isRetry()){
62+
63+
}
64+
}
65+
66+
private ParsedLine parse(String line) {
67+
if(line == null || line.isBlank()) {
68+
return new ParsedLine();
69+
} else if (line.trim().startsWith(":")){
70+
return new ParsedLine(line.substring(1));
71+
} else if (!line.contains(":")) {
72+
return new ParsedLine(line, "");
73+
} else {
74+
var spl = line.split(":");
75+
return new ParsedLine(spl[0].trim(), spl[1]);
76+
}
77+
}
78+
79+
private class ParsedLine {
80+
81+
private final String value;
82+
private final String name;
83+
84+
public ParsedLine(String value) {
85+
this(null, value);
86+
}
87+
88+
public ParsedLine(){
89+
this(null, null);
90+
}
91+
92+
public ParsedLine(String name, String value) {
93+
this.name = name;
94+
if(value == null){
95+
this.value = null;
96+
} else if (value.startsWith(" ")) {
97+
this.value = value.substring(1);
98+
} else {
99+
this.value = value;
100+
}
101+
}
102+
103+
public boolean isDispatch() {
104+
return name == null && value == null;
105+
}
106+
107+
public boolean isComment() {
108+
return name == null;
109+
}
110+
111+
public String value() {
112+
return value;
113+
}
114+
115+
public String name() {
116+
return name;
117+
}
118+
119+
public boolean isData() {
120+
return name != null && name.equalsIgnoreCase("data");
121+
}
122+
123+
public boolean isEvent() {
124+
return name != null && name.equalsIgnoreCase("event");
125+
}
126+
127+
public boolean isId() {
128+
return name != null
129+
&& name.equalsIgnoreCase("id")
130+
&& value != null;
131+
}
132+
133+
public boolean isRetry() {
134+
return value == null && name != null
135+
&& name.matches("^\\d+$");
136+
137+
}
138+
}
139+
140+
141+
private class EventBuffer {
142+
String id = "";
143+
String type = "";
144+
StringBuffer buffer = new StringBuffer();
145+
146+
public SseEvent toEvent() {
147+
return new SseEvent(id, type, getValue());
148+
}
149+
150+
private String getValue() {
151+
String string = buffer.toString();
152+
if(string.endsWith("\n")){
153+
return string.substring(0, string.length() -1);
154+
}
155+
return string;
156+
}
23157
}
24158
}

0 commit comments

Comments
 (0)