Skip to content

Commit fe091f6

Browse files
committed
Add proxy config param and make use of it in the sender to allow sending payloads through a proxy
1 parent c370ecb commit fe091f6

File tree

6 files changed

+212
-14
lines changed

6 files changed

+212
-14
lines changed

rollbar-java/src/integTest/java/com/rollbar/notifier/RollbarITest.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
import static com.github.tomakehurst.wiremock.client.WireMock.post;
77
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
88
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
9+
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
10+
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
11+
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
912
import static com.rollbar.notifier.config.ConfigBuilder.withAccessToken;
1013
import static java.lang.String.format;
1114

15+
import com.github.tomakehurst.wiremock.WireMockServer;
16+
import com.github.tomakehurst.wiremock.client.WireMock;
1217
import com.github.tomakehurst.wiremock.junit.WireMockRule;
1318
import com.google.gson.Gson;
1419
import com.google.gson.GsonBuilder;
@@ -29,6 +34,9 @@
2934
import com.rollbar.notifier.util.json.DataSerializer;
3035
import com.rollbar.notifier.util.json.LevelSerializer;
3136
import com.rollbar.notifier.util.json.PayloadSerializer;
37+
import java.net.InetSocketAddress;
38+
import java.net.Proxy;
39+
import java.net.Proxy.Type;
3240
import java.util.UUID;
3341
import org.junit.Before;
3442
import org.junit.Rule;
@@ -40,6 +48,10 @@ public class RollbarITest {
4048

4149
private static final String URL = format("http://localhost:%d/api/1/item/", PORT);
4250

51+
private static final String PROXY_HOST = "localhost";
52+
53+
private static final int PROXY_PORT = 8090;
54+
4355
private static final String ACCESS_TOKEN = UUID.randomUUID().toString();
4456

4557
private static final String ERROR_MESSAGE = "This is an error message.";
@@ -126,6 +138,73 @@ public void shouldSendSuccessfullyMessagePayload() {
126138
rollbar.error(ERROR_MESSAGE);
127139
}
128140

141+
@Test
142+
public void shouldSendSuccessfullyMessagePayloadThroughProxy() {
143+
WireMockServer wireMockServerProxy = new WireMockServer(PROXY_PORT);
144+
wireMockServerProxy.start();
145+
146+
WireMock wireMockProxy = new WireMock(PROXY_HOST, PROXY_PORT);
147+
148+
Sender sender = new SyncSender.Builder()
149+
.url(URL)
150+
.accessToken(ACCESS_TOKEN)
151+
.proxy(new Proxy(Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT)))
152+
.build();
153+
154+
ConfigBuilder configBuilder = withAccessToken(ACCESS_TOKEN)
155+
.sender(sender)
156+
.timestamp(timeProvider);
157+
158+
final String uuid = UUID.randomUUID().toString();
159+
160+
Config config = configBuilder.build();
161+
162+
Message message = new Message.Builder()
163+
.body(ERROR_MESSAGE)
164+
.build();
165+
166+
Body body = new Body.Builder()
167+
.bodyContent(message)
168+
.build();
169+
170+
Data data = new Data.Builder()
171+
.level(Level.ERROR)
172+
.body(body)
173+
.notifier(config.notifier().provide())
174+
.timestamp(timeProvider.provide())
175+
.language(config.language())
176+
.build();
177+
178+
Payload payload = new Payload.Builder()
179+
.accessToken(ACCESS_TOKEN)
180+
.data(data)
181+
.build();
182+
183+
wireMockProxy.register(
184+
post(urlMatching(".*"))
185+
.willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
186+
187+
// Note that this url doesn't end up with the slash char, it seems is getting removed after
188+
// passing through the proxy.
189+
stubFor(post(urlEqualTo("/api/1/item"))
190+
.withHeader("Accept", equalTo("application/json"))
191+
.withHeader("Accept-Charset", equalTo("UTF-8"))
192+
.withHeader("Content-Type", equalTo("application/json; charset=UTF-8"))
193+
.withHeader("x-rollbar-access-token", equalTo(ACCESS_TOKEN))
194+
.withRequestBody(equalToJson(gson.toJson(payload)))
195+
.willReturn(aResponse()
196+
.withStatus(200)
197+
.withHeader("Content-Type", "application/json")
198+
.withBody(gson.toJson(RollbarResponse.success(uuid)))));
199+
200+
sender.addListener(SenderAssertions.assertResponseSuccess(uuid));
201+
202+
Rollbar rollbar = new Rollbar(config);
203+
204+
rollbar.error(ERROR_MESSAGE);
205+
wireMockServerProxy.stop();
206+
}
207+
129208
@Test
130209
public void shouldNotifyAccessTokenRequiredError() {
131210
int responseCode = 400;

rollbar-java/src/main/java/com/rollbar/notifier/config/Config.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.rollbar.notifier.sender.Sender;
1313
import com.rollbar.notifier.transformer.Transformer;
1414
import com.rollbar.notifier.uuid.UuidGenerator;
15+
import java.net.Proxy;
1516
import java.util.Map;
1617

1718
/**
@@ -159,6 +160,13 @@ public interface Config {
159160
*/
160161
Sender sender();
161162

163+
/**
164+
* Get the {@link Proxy proxy}.
165+
*
166+
* @return the proxy.
167+
*/
168+
Proxy proxy();
169+
162170
/**
163171
* Flag to indicate that the Rollbar notifier should handle the uncaught errors.
164172
*

rollbar-java/src/main/java/com/rollbar/notifier/config/ConfigBuilder.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.rollbar.notifier.transformer.Transformer;
1818
import com.rollbar.notifier.uuid.UuidGenerator;
1919
import java.lang.Thread.UncaughtExceptionHandler;
20+
import java.net.Proxy;
2021
import java.util.Map;
2122

2223
/**
@@ -65,6 +66,8 @@ public class ConfigBuilder {
6566

6667
private Sender sender;
6768

69+
private Proxy proxy;
70+
6871
private boolean handleUncaughtErrors;
6972

7073
private boolean enabled;
@@ -105,6 +108,7 @@ private ConfigBuilder(Config config) {
105108
this.handleUncaughtErrors = config.handleUncaughtErrors();
106109
this.enabled = config.isEnabled();
107110
this.endpoint = config.endpoint();
111+
this.proxy = config.proxy();
108112
}
109113

110114
/**
@@ -334,7 +338,7 @@ public ConfigBuilder uuidGenerator(UuidGenerator uuidGenerator) {
334338
}
335339

336340
/**
337-
* Retrieve the {@link Sender sender}.
341+
* The {@link Sender sender}.
338342
*
339343
* @param sender the sender.
340344
* @return the builder instance.
@@ -344,6 +348,17 @@ public ConfigBuilder sender(Sender sender) {
344348
return this;
345349
}
346350

351+
/**
352+
* The {@link Proxy proxy} to be used to send the data.
353+
*
354+
* @param proxy the proxy.
355+
* @return the builder instance.
356+
*/
357+
public ConfigBuilder proxy(Proxy proxy) {
358+
this.proxy = proxy;
359+
return this;
360+
}
361+
347362
/**
348363
* Flag to set the default handler for uncaught errors,
349364
* see {@link UncaughtExceptionHandler}.
@@ -387,6 +402,7 @@ public Config build() {
387402
.sender(
388403
new SyncSender.Builder(this.endpoint)
389404
.accessToken(accessToken)
405+
.proxy(proxy)
390406
.build()
391407
).build();
392408
}
@@ -439,6 +455,8 @@ private static class ConfigImpl implements Config {
439455

440456
private final Sender sender;
441457

458+
private final Proxy proxy;
459+
442460
private final boolean handleUncaughtErrors;
443461

444462
private final boolean enabled;
@@ -464,6 +482,7 @@ private static class ConfigImpl implements Config {
464482
this.fingerPrintGenerator = builder.fingerPrintGenerator;
465483
this.uuidGenerator = builder.uuidGenerator;
466484
this.sender = builder.sender;
485+
this.proxy = builder.proxy;
467486
this.handleUncaughtErrors = builder.handleUncaughtErrors;
468487
this.enabled = builder.enabled;
469488
}
@@ -568,6 +587,11 @@ public Sender sender() {
568587
return sender;
569588
}
570589

590+
@Override
591+
public Proxy proxy() {
592+
return proxy;
593+
}
594+
571595
@Override
572596
public boolean handleUncaughtErrors() {
573597
return handleUncaughtErrors;

rollbar-java/src/main/java/com/rollbar/notifier/sender/SyncSender.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import com.rollbar.notifier.sender.result.Response;
77
import com.rollbar.notifier.sender.result.Result;
88
import com.rollbar.notifier.util.ObjectsUtils;
9-
109
import java.io.BufferedReader;
1110
import java.io.IOException;
1211
import java.io.InputStream;
1312
import java.io.InputStreamReader;
1413
import java.io.OutputStream;
1514
import java.net.HttpURLConnection;
1615
import java.net.MalformedURLException;
16+
import java.net.Proxy;
1717
import java.net.URL;
1818

1919
/**
@@ -31,10 +31,13 @@ public class SyncSender extends AbstractSender {
3131

3232
private final String accessToken;
3333

34+
private final Proxy proxy;
35+
3436
SyncSender(Builder builder) {
3537
this.url = builder.url;
3638
this.jsonSerializer = builder.jsonSerializer;
3739
this.accessToken = builder.accessToken;
40+
this.proxy = builder.proxy != null ? builder.proxy : Proxy.NO_PROXY;
3841
}
3942

4043
@Override
@@ -56,7 +59,7 @@ private Response send(String body) throws IOException {
5659
}
5760

5861
private HttpURLConnection getConnection() throws IOException {
59-
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
62+
HttpURLConnection connection = (HttpURLConnection) url.openConnection(this.proxy);
6063

6164
if (accessToken != null && !"".equals(accessToken)) {
6265
connection.setRequestProperty("x-rollbar-access-token", accessToken);
@@ -114,6 +117,9 @@ private static String getResponseContent(HttpURLConnection connection) throws IO
114117
return buffer.toString();
115118
}
116119

120+
/**
121+
* Builder class for {@link SyncSender}.
122+
*/
117123
public static final class Builder {
118124

119125
private URL url;
@@ -122,35 +128,77 @@ public static final class Builder {
122128

123129
private String accessToken;
124130

131+
private Proxy proxy;
132+
125133
public Builder() {
126134
this(DEFAULT_API_ENDPOINT);
127135
}
128136

137+
/**
138+
* Constructor.
139+
* @param url the url.
140+
*/
129141
public Builder(String url) {
130142
this.url = parseUrl(url);
131143
this.jsonSerializer = new JsonSerializerImpl();
144+
this.proxy = null;
132145
}
133146

147+
/**
148+
* The url as string.
149+
* @param url the url
150+
* @return the builder instance.
151+
*/
134152
public Builder url(String url) {
135153
this.url = parseUrl(url);
136154
return this;
137155
}
138156

157+
/**
158+
* The url as {@link URL}.
159+
* @param url the url
160+
* @return the builder instance.
161+
*/
139162
public Builder url(URL url) {
140163
this.url = url;
141164
return this;
142165
}
143166

167+
/**
168+
* The {@link JsonSerializer json serializer}.
169+
* @param jsonSerializer the json serializer.
170+
* @return the builder instance.
171+
*/
144172
public Builder jsonSerializer(JsonSerializer jsonSerializer) {
145173
this.jsonSerializer = jsonSerializer;
146174
return this;
147175
}
148176

177+
/**
178+
* The rollbar access token.
179+
* @param accessToken the access token.
180+
* @return the builder instance.
181+
*/
149182
public Builder accessToken(String accessToken) {
150183
this.accessToken = accessToken;
151184
return this;
152185
}
153186

187+
/**
188+
* The {@link Proxy proxy}.
189+
* @param proxy the proxy.
190+
* @return the builder instance.
191+
*/
192+
public Builder proxy(Proxy proxy) {
193+
this.proxy = proxy;
194+
return this;
195+
}
196+
197+
/**
198+
* Builds the {@link SyncSender sync sender}.
199+
*
200+
* @return the sync sender.
201+
*/
154202
public SyncSender build() {
155203
return new SyncSender(this);
156204
}

0 commit comments

Comments
 (0)