This is an example project that shows how to easily integrate java-ngrok
with Dropwizard.
Create
a NgrokConfiguration
class that lets us use the config to enable ngrok
and pass it some useful parameters.
public class NgrokConfiguration {
@JsonProperty
private boolean enabled = false;
@JsonProperty
private String region;
public boolean isEnabled() {
return enabled;
}
public String getRegion() {
return region;
}
}
Then wire this class as a JsonProperty
to the Dropwizard Configuration for our Application.
public class JavaNgrokExampleDropwizardConfiguration extends Configuration {
@JsonProperty
private String environment = "dev";
@JsonProperty("ngrok")
private NgrokConfiguration ngrokConfiguration;
public String getEnvironment() {
return environment;
}
public NgrokConfiguration getNgrokConfiguration() {
return ngrokConfiguration;
}
}
And pass parameters to our Dropwizard application through our config file:
ngrok:
enabled: true
If ngrok.enabled
config flag is set, we want to initialize java-ngrok
when Dropwizard is booting. An easy place to do
this is in the run()
method of the Application.
public class JavaNgrokExampleDropwizardApplication extends Application<JavaNgrokExampleDropwizardConfiguration> {
private static final Logger LOGGER = Logger.getLogger(String.valueOf(JavaNgrokExampleDropwizardApplication.class));
@Override
public void run(final JavaNgrokExampleDropwizardConfiguration configuration,
final Environment environment) {
// java-ngrok will only be installed, and should only ever be initialized, in a dev environment
if (configuration.getEnvironment().equals("dev") &&
configuration.getNgrokConfiguration().isEnabled() &&
isNotBlank(System.getenv("NGROK_AUTHTOKEN"))) {
final JavaNgrokConfig javaNgrokConfig = new JavaNgrokConfig.Builder()
.withRegion(nonNull(configuration.getNgrokConfiguration().getRegion()) ? Region.valueOf(configuration.getNgrokConfiguration().getRegion().toUpperCase()) : null)
.build();
final NgrokClient ngrokClient = new NgrokClient.Builder()
.withJavaNgrokConfig(javaNgrokConfig)
.build();
final int port = getPort(configuration);
final CreateTunnel createTunnel = new CreateTunnel.Builder()
.withAddr(port)
.build();
final Tunnel tunnel = ngrokClient.connect(createTunnel);
LOGGER.info(String.format("ngrok tunnel \"%s\" -> \"http://127.0.0.1:%d\"", tunnel.getPublicUrl(), port));
// Update any base URLs or webhooks to use the public ngrok URL
initWebhooks(tunnel.getPublicUrl());
}
}
private int getPort(JavaNgrokExampleDropwizardConfiguration configuration) {
final Stream<ConnectorFactory> connectors = configuration.getServerFactory() instanceof DefaultServerFactory
? ((DefaultServerFactory) configuration.getServerFactory()).getApplicationConnectors().stream()
: Stream.of((SimpleServerFactory) configuration.getServerFactory()).map(SimpleServerFactory::getConnector);
return connectors.filter(connector -> connector.getClass().isAssignableFrom(HttpConnectorFactory.class))
.map(connector -> (HttpConnectorFactory) connector)
.mapToInt(HttpConnectorFactory::getPort)
.findFirst()
.orElseThrow(IllegalStateException::new);
}
private void initWebhooks(final String publicUrl) {
// Update inbound traffic via APIs to use the public-facing ngrok URL
}
// ... The rest of our Dropwizard application
}
Now Dropwizard can be started by the usual means, setting ngrok.enabled
in the config to open a tunnel.
- Run
make build
to build the application - Start application with
java -jar target/java-ngrok-example-dropwizard-1.0.0-SNAPSHOT.jar server src/main/resources/config.yml
- Check the logs for the
ngrok
tunnel's public URL, which should tunnel tohttp://localhost:8080