Skip to content

Commit 9bcf314

Browse files
committed
create UserServiceFactory
1 parent fca583e commit 9bcf314

File tree

5 files changed

+104
-194
lines changed

5 files changed

+104
-194
lines changed

src/main/java/io/getstream/chat/java/services/framework/DefaultClient.java

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import io.jsonwebtoken.Jwts;
99
import io.jsonwebtoken.SignatureAlgorithm;
1010
import java.io.IOException;
11-
import java.lang.reflect.Proxy;
1211
import java.nio.charset.StandardCharsets;
1312
import java.security.Key;
1413
import java.time.Duration;
@@ -32,6 +31,7 @@ public class DefaultClient implements Client {
3231
private static volatile DefaultClient defaultInstance;
3332
@NotNull private OkHttpClient okHttpClient;
3433
@NotNull private Retrofit retrofit;
34+
@NotNull private UserServiceFactory serviceFactory;
3535
@NotNull private final String apiSecret;
3636
@NotNull private final String apiKey;
3737
@NotNull private final Properties extendedProperties;
@@ -76,6 +76,7 @@ public DefaultClient(Properties properties) {
7676
this.apiSecret = apiSecret.toString();
7777
this.apiKey = apiKey.toString();
7878
this.retrofit = buildRetrofitClient();
79+
this.serviceFactory = new UserServiceFactory(retrofit);
7980
}
8081

8182
private Retrofit buildRetrofitClient() {
@@ -154,12 +155,7 @@ public <TService> TService create(Class<TService> svcClass) {
154155

155156
@Override
156157
public <TService> @NotNull TService create(Class<TService> svcClass, String userToken) {
157-
TService service = retrofit.create(svcClass);
158-
return (TService) Proxy.newProxyInstance(
159-
svcClass.getClassLoader(),
160-
new Class<?>[] { svcClass },
161-
new UserTokenCallProxy(okHttpClient, service, new UserToken(userToken))
162-
);
158+
return serviceFactory.create(svcClass, new UserToken(userToken));
163159
}
164160

165161
public <TService> @NotNull TService create2(Class<TService> svcClass, String userToken) {
@@ -281,57 +277,4 @@ private static boolean hasFailOnUnknownProperties(@NotNull Properties properties
281277
var hasEnabled = properties.getOrDefault(propName, "false");
282278
return Boolean.parseBoolean(hasEnabled.toString());
283279
}
284-
285-
private static class UserCall<T> implements retrofit2.Call<T> {
286-
private final retrofit2.Call<T> delegate;
287-
private final UserToken token;
288-
289-
UserCall(retrofit2.Call<T> delegate, UserToken token) {
290-
this.delegate = delegate;
291-
this.token = token;
292-
}
293-
294-
@Override
295-
public retrofit2.Response<T> execute() throws IOException {
296-
return delegate.execute();
297-
}
298-
299-
@Override
300-
public void enqueue(retrofit2.Callback<T> callback) {
301-
delegate.enqueue(callback);
302-
}
303-
304-
@Override
305-
public boolean isExecuted() {
306-
return delegate.isExecuted();
307-
}
308-
309-
@Override
310-
public void cancel() {
311-
delegate.cancel();
312-
}
313-
314-
@Override
315-
public boolean isCanceled() {
316-
return delegate.isCanceled();
317-
}
318-
319-
@Override
320-
public retrofit2.Call<T> clone() {
321-
return new UserCall<>(delegate.clone(), token);
322-
}
323-
324-
@Override
325-
public Request request() {
326-
Request original = delegate.request();
327-
return original.newBuilder()
328-
.tag(UserToken.class, token)
329-
.build();
330-
}
331-
332-
@Override
333-
public okio.Timeout timeout() {
334-
return delegate.timeout();
335-
}
336-
}
337280
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.getstream.chat.java.services.framework;
2+
3+
import okhttp3.Request;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.io.IOException;
7+
8+
public class UserCall<T> implements retrofit2.Call<T> {
9+
private final retrofit2.Call<T> delegate;
10+
private final UserToken token;
11+
12+
UserCall(retrofit2.Call<T> delegate, UserToken token) {
13+
this.delegate = delegate;
14+
this.token = token;
15+
}
16+
17+
@Override
18+
public @NotNull retrofit2.Response<T> execute() throws IOException {
19+
return delegate.execute();
20+
}
21+
22+
@Override
23+
public void enqueue(@NotNull retrofit2.Callback<T> callback) {
24+
delegate.enqueue(callback);
25+
}
26+
27+
@Override
28+
public boolean isExecuted() {
29+
return delegate.isExecuted();
30+
}
31+
32+
@Override
33+
public void cancel() {
34+
delegate.cancel();
35+
}
36+
37+
@Override
38+
public boolean isCanceled() {
39+
return delegate.isCanceled();
40+
}
41+
42+
@Override
43+
public @NotNull retrofit2.Call<T> clone() {
44+
return new UserCall<>(delegate.clone(), token);
45+
}
46+
47+
@Override
48+
public @NotNull Request request() {
49+
Request original = delegate.request();
50+
return original.newBuilder()
51+
.tag(UserToken.class, token)
52+
.build();
53+
}
54+
55+
@Override
56+
public @NotNull okio.Timeout timeout() {
57+
return delegate.timeout();
58+
}
59+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.getstream.chat.java.services.framework;
2+
3+
import retrofit2.Retrofit;
4+
5+
import static java.lang.reflect.Proxy.newProxyInstance;
6+
7+
class UserServiceFactory {
8+
9+
private final Retrofit retrofit;
10+
11+
public UserServiceFactory(Retrofit retrofit) {
12+
this.retrofit = retrofit;
13+
}
14+
15+
@SuppressWarnings("unchecked")
16+
public final <TService> TService create(Class<TService> svcClass, UserToken userToken) {
17+
return (TService) newProxyInstance(
18+
svcClass.getClassLoader(),
19+
new Class<?>[] { svcClass },
20+
new UserTokenCallProxy(retrofit.callFactory(), retrofit.create(svcClass), userToken)
21+
);
22+
}
23+
24+
}

src/main/java/io/getstream/chat/java/services/framework/UserTokenCallAdapterFactory.java

Lines changed: 0 additions & 117 deletions
This file was deleted.

src/test/java/io/getstream/chat/java/CustomTest.java

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,36 @@
55
import io.getstream.chat.java.services.framework.DefaultClient;
66
import org.junit.jupiter.api.Test;
77
import java.lang.management.ManagementFactory;
8+
import java.util.concurrent.TimeUnit;
89

910
public class CustomTest {
1011

1112
@Test
1213
void customTest() throws Exception {
13-
var userId = "han_solo";
14-
var userToken = User.createToken("han_solo", null, null);
14+
var userId = "admin";
15+
var userToken = User.createToken(userId, null, null);
1516
var response = User.list().userId(userId).filterCondition("id", userId).request();
1617
System.out.println(response);
1718
}
1819

1920

2021
@Test
2122
void userReqTest() throws Exception {
22-
var userId = "han_solo";
23-
var userToken = User.createToken("han_solo", null, null);
23+
var userId = "admin";
24+
var userToken = User.createToken(userId, null, null);
2425
var response = User.list().filterCondition("id", userId).withUserToken(userToken).request();
25-
System.out.println("\n> " + response + "\n");
26+
System.out.println("\n!.!.! " + response + "\n");
2627
}
2728

2829
@Test
2930
void measureClientCreate() throws Exception {
30-
var userId = "han_solo";
31+
var userId = "admin";
3132
var userToken = User.createToken(userId, null, null);
3233

3334
// Test creating a UserClient directly - should use Client-Side auth
3435
var defaultClient = new DefaultClient();
3536

36-
var iterations = 10_000_000;
37+
var iterations = 100_000_000;
3738

3839
// Warm up JVM to avoid cold start effects
3940
for (int i = 0; i < 10_000; i++) {
@@ -53,14 +54,14 @@ void measureClientCreate() throws Exception {
5354
}
5455
long endTime = System.nanoTime();
5556
long allocatedAfter1 = threadBean.getCurrentThreadAllocatedBytes();
56-
long elapsedTime1 = endTime - startTime;
57+
long elapsedTimeInNs1 = endTime - startTime;
5758
long allocated1 = allocatedAfter1 - allocatedBefore1;
5859

5960
System.out.println("=========================================================");
6061

61-
System.out.println("> First loop elapsed time: " + (elapsedTime1 / 1_000_000) + " ms");
62+
System.out.println("> First loop elapsed time: " + TimeUnit.NANOSECONDS.toMillis(elapsedTimeInNs1) + " ms");
6263
System.out.println("> First loop memory allocated: " + (allocated1 / 1024 / 1024) + " MB");
63-
System.out.println("> First loop avg time per call: " + (elapsedTime1 / (double) iterations) + " ns");
64+
System.out.println("> First loop avg time per call: " + (elapsedTimeInNs1 / (double) iterations) + " ns");
6465
System.out.println("> First loop avg memory per call: " + (allocated1 / (double) iterations) + " bytes");
6566

6667
// Measure second test
@@ -71,20 +72,20 @@ void measureClientCreate() throws Exception {
7172
}
7273
endTime = System.nanoTime();
7374
long allocatedAfter2 = threadBean.getCurrentThreadAllocatedBytes();
74-
long elapsedTime2 = endTime - startTime;
75+
long elapsedTimeInNs2 = endTime - startTime;
7576
long allocated2 = allocatedAfter2 - allocatedBefore2;
7677

77-
System.out.println("> Second loop elapsed time: " + (elapsedTime2 / 1_000_000) + " ms");
78+
System.out.println("> Second loop elapsed time: " + TimeUnit.NANOSECONDS.toMillis(elapsedTimeInNs2) + " ms");
7879
System.out.println("> Second loop memory allocated: " + (allocated2 / 1024 / 1024) + " MB");
79-
System.out.println("> Second loop avg time per call: " + (elapsedTime2 / (double) iterations) + " ns");
80+
System.out.println("> Second loop avg time per call: " + (elapsedTimeInNs2 / (double) iterations) + " ns");
8081
System.out.println("> Second loop avg memory per call: " + (allocated2 / (double) iterations) + " bytes");
8182

8283
// Performance comparison
83-
if (elapsedTime1 < elapsedTime2) {
84-
double timesFaster = (double) elapsedTime2 / elapsedTime1;
84+
if (elapsedTimeInNs1 < elapsedTimeInNs2) {
85+
double timesFaster = (double) elapsedTimeInNs2 / elapsedTimeInNs1;
8586
System.out.println("> create is " + String.format("%.2fx", timesFaster) + " faster than create2");
8687
} else {
87-
double timesFaster = (double) elapsedTime1 / elapsedTime2;
88+
double timesFaster = (double) elapsedTimeInNs1 / elapsedTimeInNs2;
8889
System.out.println("> create2 is " + String.format("%.2fx", timesFaster) + " faster than create");
8990
}
9091

@@ -96,6 +97,6 @@ void measureClientCreate() throws Exception {
9697
System.out.println("> create2 allocates " + String.format("%.2fx", timesLess) + " less memory than create");
9798
}
9899

99-
System.out.println("======================================================================");
100+
System.out.println("=========================================================");
100101
}
101102
}

0 commit comments

Comments
 (0)