Skip to content

Commit

Permalink
Redesigned the reverse proxy API.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmihajlovski committed Aug 19, 2016
1 parent d65a451 commit 039eae7
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 32 deletions.
2 changes: 2 additions & 0 deletions rapidoid-commons/src/main/resources/rapidoid-classes.txt
Expand Up @@ -539,8 +539,10 @@ org.rapidoid.render.XNode
org.rapidoid.reverseproxy.AbstractReverseProxyBean
org.rapidoid.reverseproxy.LoadBalancer
org.rapidoid.reverseproxy.ProxyMapping
org.rapidoid.reverseproxy.ProxyUpstream
org.rapidoid.reverseproxy.Reverse
org.rapidoid.reverseproxy.ReverseProxy
org.rapidoid.reverseproxy.ReverseProxyMapDSL
org.rapidoid.reverseproxy.RoundRobinLoadBalancer
org.rapidoid.scan.ClasspathUtil
org.rapidoid.scan.Scan
Expand Down
Expand Up @@ -24,10 +24,12 @@
import org.rapidoid.annotation.Since;
import org.rapidoid.http.Req;

import java.util.List;

@Authors("Nikolche Mihajlovski")
@Since("5.2.0")
public interface LoadBalancer {

String getTargetUrl(Req req);
ProxyUpstream pickUpstream(Req req, List<ProxyUpstream> candidates);

}
Expand Up @@ -23,6 +23,7 @@
import org.rapidoid.RapidoidThing;
import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.commons.Str;
import org.rapidoid.http.Req;

import java.util.List;
Expand All @@ -33,29 +34,38 @@ public class ProxyMapping extends RapidoidThing {

private final String prefix;

private final List<String> targets;
private volatile List<ProxyUpstream> upstreams;

private volatile LoadBalancer loadBalancer = new RoundRobinLoadBalancer(this);
private volatile LoadBalancer loadBalancer = new RoundRobinLoadBalancer();

public ProxyMapping(String prefix, List<String> targets) {
public ProxyMapping(String prefix, List<ProxyUpstream> upstreams) {
this.prefix = prefix;
this.targets = targets;
this.upstreams = upstreams;
}

public String prefix() {
return prefix;
}

public List<String> targets() {
return targets;
public List<ProxyUpstream> upstreams() {
return upstreams;
}

public ProxyMapping upstreams(List<ProxyUpstream> upstreams) {
this.upstreams = upstreams;
return this;
}

public boolean matches(Req req) {
return req.path().startsWith(prefix);
}

public String getTargetUrl(Req req) {
return loadBalancer.getTargetUrl(req);
ProxyUpstream upstream = loadBalancer.pickUpstream(req, upstreams);

String trimmed = Str.triml(req.uri(), prefix());

return upstream.url() + trimmed;
}

public LoadBalancer loadBalancer() {
Expand Down
@@ -0,0 +1,40 @@
package org.rapidoid.reverseproxy;

/*
* #%L
* rapidoid-http-server
* %%
* Copyright (C) 2014 - 2016 Nikolche Mihajlovski and contributors
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/

import org.rapidoid.RapidoidThing;
import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;

@Authors("Nikolche Mihajlovski")
@Since("5.2.0")
public class ProxyUpstream extends RapidoidThing {

private final String url;

public ProxyUpstream(String url) {
this.url = url;
}

public String url() {
return url;
}
}
Expand Up @@ -6,15 +6,14 @@
import org.rapidoid.concurrent.Callback;
import org.rapidoid.http.*;
import org.rapidoid.http.impl.HttpIO;
import org.rapidoid.log.Log;
import org.rapidoid.u.U;

import java.util.List;
import java.util.Map;

/*
* #%L
* rapidoid-web
* rapidoid-http-server
* %%
* Copyright (C) 2014 - 2016 Nikolche Mihajlovski and contributors
* %%
Expand Down Expand Up @@ -124,13 +123,12 @@ protected HttpClient createClient() {
.maxConnPerRoute(maxConnPerRoute());
}

public ProxyMapping map(String uriPrefix, List<String> targets) {
Log.info("Reverse proxy mapping", "!uriPrefix", uriPrefix, "!targets", targets);

ProxyMapping mapping = new ProxyMapping(uriPrefix, targets);
mappings.add(mapping);
public ReverseProxyMapDSL map(String uriPrefix) {
return new ReverseProxyMapDSL(this, uriPrefix);
}

return mapping;
public List<ProxyMapping> mappings() {
return mappings;
}

}
@@ -0,0 +1,63 @@
package org.rapidoid.reverseproxy;

import org.rapidoid.RapidoidThing;
import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.log.Log;
import org.rapidoid.u.U;

import java.util.List;

/*
* #%L
* rapidoid-http-server
* %%
* Copyright (C) 2014 - 2016 Nikolche Mihajlovski and contributors
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/

@Authors("Nikolche Mihajlovski")
@Since("5.2.0")
public class ReverseProxyMapDSL extends RapidoidThing {

private final ReverseProxy proxy;

private final String uriPrefix;

public ReverseProxyMapDSL(ReverseProxy proxy, String uriPrefix) {
this.proxy = proxy;
this.uriPrefix = uriPrefix;
}

public ProxyMapping to(String... upstreams) {
return to(U.list(upstreams));
}

public ProxyMapping to(List<String> upstreams) {
Log.info("Reverse proxy mapping", "!uriPrefix", uriPrefix, "!upstreams", upstreams);

List<ProxyUpstream> proxyUpstreams = U.list();

for (String upstream : upstreams) {
proxyUpstreams.add(new ProxyUpstream(upstream));
}

ProxyMapping mapping = new ProxyMapping(uriPrefix, proxyUpstreams);
proxy.mappings().add(mapping);

return mapping;
}

}
Expand Up @@ -23,7 +23,6 @@
import org.rapidoid.RapidoidThing;
import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.commons.Str;
import org.rapidoid.http.Req;

import java.util.List;
Expand All @@ -33,24 +32,15 @@
@Since("5.2.0")
public class RoundRobinLoadBalancer extends RapidoidThing implements LoadBalancer {

private final ProxyMapping mapping;

private final AtomicLong counter = new AtomicLong();

public RoundRobinLoadBalancer(ProxyMapping mapping) {
this.mapping = mapping;
}

@Override
public String getTargetUrl(Req req) {
long n = counter.incrementAndGet();
public ProxyUpstream pickUpstream(Req req, List<ProxyUpstream> candidates) {
long n = counter.getAndIncrement();

List<String> targets = mapping.targets();
int index = (int) (n % targets.size());
String target = targets.get(index);
int index = (int) (n % candidates.size());

String trimmed = Str.triml(req.uri(), mapping.prefix());
return target + trimmed;
return candidates.get(index);
}

}
Expand Up @@ -251,10 +251,10 @@ public static AppBootstrap bootstrap(String... args) {

private static void processProxyArg(String arg) {
String[] parts = arg.split("->");

U.must(parts.length == 2, "Expected /uri->target proxy mapping!");

List<String> targets = U.list(parts[1].split("\\,"));
Reverse.proxy().map(parts[0], targets);
Reverse.proxy().map(parts[0]).to(parts[1].split("\\,"));
}

static void filterAndInvokeMainClasses(Object[] beans) {
Expand Down

0 comments on commit 039eae7

Please sign in to comment.