Skip to content

Commit 1d8e3c9

Browse files
committed
fix batch 2
1 parent 0f14fde commit 1d8e3c9

File tree

8 files changed

+256
-22
lines changed

8 files changed

+256
-22
lines changed

src/main/java/io/vertx/httpproxy/HttpProxy.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.vertx.codegen.annotations.VertxGen;
1616
import io.vertx.core.Future;
1717
import io.vertx.core.Handler;
18+
import io.vertx.core.Vertx;
1819
import io.vertx.core.http.HttpClient;
1920
import io.vertx.core.http.HttpClientRequest;
2021
import io.vertx.core.http.HttpServerRequest;

src/main/java/io/vertx/httpproxy/cache/CacheOptions.java

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import io.vertx.codegen.annotations.DataObject;
44
import io.vertx.codegen.json.annotations.JsonGen;
55
import io.vertx.core.json.JsonObject;
6-
import io.vertx.httpproxy.impl.CacheImpl;
7-
import io.vertx.httpproxy.spi.cache.Cache;
6+
7+
import java.util.Objects;
88

99
/**
1010
* Cache options.
@@ -13,19 +13,53 @@
1313
@JsonGen(publicConverter = false)
1414
public class CacheOptions {
1515

16+
/**
17+
* Default max size of the cache = 1000
18+
*/
1619
public static final int DEFAULT_MAX_SIZE = 1000;
1720

21+
/**
22+
* Actual name of anonymous shared cache = {@code __vertx.DEFAULT}
23+
*/
24+
public static final String DEFAULT_NAME = "__vertx.DEFAULT";
25+
26+
/**
27+
* Default shared cache = {@code false}
28+
*/
29+
public static final boolean DEFAULT_SHARED = false;
30+
1831
private int maxSize = DEFAULT_MAX_SIZE;
32+
private String name = DEFAULT_NAME;
33+
private boolean shared = DEFAULT_SHARED;
1934

35+
/**
36+
* Default constructor
37+
*/
2038
public CacheOptions() {
2139
}
2240

41+
/**
42+
* Copy constructor
43+
*
44+
* @param other the options to copy
45+
*/
46+
public CacheOptions(CacheOptions other) {
47+
this.maxSize = other.getMaxSize();
48+
this.name = other.getName();
49+
this.shared = other.getShared();
50+
}
51+
52+
/**
53+
* Constructor to create an options from JSON
54+
*
55+
* @param json the JSON
56+
*/
2357
public CacheOptions(JsonObject json) {
2458
CacheOptionsConverter.fromJson(json, this);
2559
}
2660

2761
/**
28-
* @return the max number of entries the cache can hold
62+
* @return the max number of entries the cache can hold.
2963
*/
3064
public int getMaxSize() {
3165
return maxSize;
@@ -45,15 +79,55 @@ public CacheOptions setMaxSize(int maxSize) {
4579
return this;
4680
}
4781

48-
public Cache newCache() {
49-
return new CacheImpl(this);
82+
/**
83+
* @return the cache name used for sharing
84+
*/
85+
public String getName() {
86+
return this.name;
87+
}
88+
89+
/**
90+
* Set the cache name, used when the cache is shared, otherwise ignored.
91+
* @param name the new name
92+
* @return a reference to this, so the API can be used fluently
93+
*/
94+
public CacheOptions setName(String name) {
95+
Objects.requireNonNull(name, "Client name cannot be null");
96+
this.name = name;
97+
return this;
98+
}
99+
100+
/**
101+
* @return whether the cache is shared
102+
*/
103+
public boolean getShared() {
104+
return shared;
105+
}
106+
107+
/**
108+
* Set to {@code true} to share the cache.
109+
*
110+
* <p> There can be multiple shared caches distinguished by {@link #getName()}, when no specific
111+
* name is set, the {@link #DEFAULT_NAME} is used.
112+
*
113+
* @param shared {@code true} to use a shared client
114+
* @return a reference to this, so the API can be used fluently
115+
*/
116+
public CacheOptions setShared(boolean shared) {
117+
this.shared = shared;
118+
return this;
50119
}
51120

52121
@Override
53122
public String toString() {
54123
return toJson().toString();
55124
}
56125

126+
/**
127+
* Convert to JSON
128+
*
129+
* @return the JSON
130+
*/
57131
public JsonObject toJson() {
58132
JsonObject json = new JsonObject();
59133
CacheOptionsConverter.toJson(this, json);
Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.vertx.httpproxy.impl;
22

33
import io.vertx.core.Future;
4+
import io.vertx.core.Vertx;
45
import io.vertx.httpproxy.cache.CacheOptions;
56
import io.vertx.httpproxy.spi.cache.Cache;
67
import io.vertx.httpproxy.spi.cache.Resource;
@@ -16,25 +17,22 @@
1617
public class CacheImpl implements Cache {
1718

1819
private final int maxSize;
19-
private final Map<String, Resource> data;
20-
private final LinkedList<String> records;
20+
private final LinkedHashMap<String, Resource> data;
2121

2222
public CacheImpl(CacheOptions options) {
2323
this.maxSize = options.getMaxSize();
24-
this.data = new HashMap<>();
25-
this.records = new LinkedList<>();
24+
this.data = new LinkedHashMap<>() {
25+
@Override
26+
protected boolean removeEldestEntry(Map.Entry<String, Resource> eldest) {
27+
return size() > maxSize;
28+
}
29+
};
2630
}
2731

2832

2933
@Override
3034
public Future<Void> put(String key, Resource value) {
31-
while (records.size() >= maxSize) {
32-
String toRemove = records.removeLast();
33-
data.remove(toRemove);
34-
}
35-
3635
data.put(key, value);
37-
records.addFirst(key);
3836
return Future.succeededFuture();
3937
}
4038

@@ -45,8 +43,12 @@ public Future<Resource> get(String key) {
4543

4644
@Override
4745
public Future<Void> remove(String key) {
48-
records.remove(key);
4946
data.remove(key);
5047
return Future.succeededFuture();
5148
}
49+
50+
@Override
51+
public Future<Void> close() {
52+
return Future.succeededFuture();
53+
}
5254
}

src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
package io.vertx.httpproxy.impl;
1212

1313
import io.vertx.core.Future;
14+
import io.vertx.core.Vertx;
1415
import io.vertx.core.http.*;
16+
import io.vertx.core.internal.CloseFuture;
17+
import io.vertx.core.internal.VertxInternal;
18+
import io.vertx.core.internal.http.*;
1519
import io.vertx.core.internal.logging.Logger;
1620
import io.vertx.core.internal.logging.LoggerFactory;
1721
import io.vertx.core.net.NetSocket;
@@ -33,13 +37,27 @@ public class ReverseProxy implements HttpProxy {
3337
public ReverseProxy(ProxyOptions options, HttpClient client) {
3438
CacheOptions cacheOptions = options.getCacheOptions();
3539
if (cacheOptions != null) {
36-
Cache cache = cacheOptions.newCache();
40+
Cache cache = newCache(cacheOptions, ((HttpClientInternal) client).vertx());
3741
addInterceptor(new CachingFilter(cache));
3842
}
3943
this.client = client;
4044
this.supportWebSocket = options.getSupportWebSocket();
4145
}
4246

47+
public Cache newCache(CacheOptions options, Vertx vertx) {
48+
if (options.getShared()) {
49+
CloseFuture closeFuture = new CloseFuture();
50+
return ((VertxInternal) vertx).createSharedResource("__vertx.shared.proxyCache", options.getName(), closeFuture, (cf_) -> {
51+
Cache cache = new CacheImpl(options);
52+
cf_.add(completion -> {
53+
cache.close().onComplete(completion);
54+
});
55+
return cache;
56+
});
57+
}
58+
return new CacheImpl(options);
59+
}
60+
4361
@Override
4462
public HttpProxy originRequestProvider(BiFunction<HttpServerRequest, HttpClient, Future<HttpClientRequest>> provider) {
4563
selector = provider;
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.vertx.httpproxy.spi.cache;
22

33
import io.vertx.core.Future;
4+
import io.vertx.core.dns.SrvRecord;
45

56

67
/**
@@ -9,7 +10,9 @@
910
public interface Cache {
1011

1112
/**
12-
* Being called when the cache attempts to add a new cache item.
13+
* Being called when the proxy attempts to add a new cache item.
14+
* The cache can only store up to maxSize of the latest items based
15+
* on CacheOptions.
1316
*
1417
* @param key the URI of the resource
1518
* @param value the cached response
@@ -18,20 +21,27 @@ public interface Cache {
1821
Future<Void> put(String key, Resource value);
1922

2023
/**
21-
* Being called when the cache attempts to fetch a cache item.
24+
* Being called when the proxy attempts to fetch a cache item.
2225
*
2326
* @param key the URI of the resource
2427
* @return the cached response, null if not exist
2528
*/
2629
Future<Resource> get(String key);
2730

2831
/**
29-
* Being called when the cache attempts to delete a cache item,
32+
* Being called when the proxy attempts to delete a cache item,
3033
* typically caused by invalidating an existing item. Do nothing
3134
* if not exist.
3235
*
3336
* @param key the URI of the resource
3437
* @return a succeed void future
3538
*/
3639
Future<Void> remove(String key);
40+
41+
/**
42+
* Being called when need to close the cache.
43+
*
44+
* @return a succeed void future
45+
*/
46+
Future<Void> close();
3747
}

src/main/java/io/vertx/httpproxy/spi/cache/Resource.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@
1818
import io.vertx.httpproxy.ProxyResponse;
1919
import io.vertx.httpproxy.impl.ParseUtils;
2020

21+
import java.nio.charset.Charset;
22+
import java.nio.charset.StandardCharsets;
2123
import java.time.Instant;
2224

2325
/**
2426
* The cached object.
2527
*/
2628
public class Resource implements ClusterSerializable {
2729

28-
private static final String UTF_8 = "utf-8";
30+
private static final Charset UTF_8 = StandardCharsets.UTF_8;
2931

3032
private String absoluteUri;
3133
private int statusCode;
@@ -148,7 +150,7 @@ private static Buffer readBuffer(Buffer buffer, Cursor cursor) {
148150
}
149151

150152
private static void appendString(Buffer buffer, String string) {
151-
appendBuffer(buffer, string == null ? null : Buffer.buffer(string, UTF_8));
153+
appendBuffer(buffer, string == null ? null : Buffer.buffer(string.getBytes(UTF_8)));
152154
}
153155

154156
private static String readString(Buffer buffer, Cursor cursor) {

0 commit comments

Comments
 (0)