package org.robotninjas.riemann.pubsub; import com.google.common.base.Charsets; import com.google.common.base.Supplier; import com.google.common.base.Throwables; import com.google.inject.Inject; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; import org.jboss.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; import org.jboss.netty.handler.codec.http.websocketx.WebSocketVersion; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.concurrent.Executor; public class RiemannPubSubClient { private final WebSocketClientHandshakerFactory handshakerFactory; private final Supplier<ClientBootstrap> bootstrapSupplier; private final Executor resultExecutor; private final String address; private final int port; @Inject public RiemannPubSubClient(String address, int port, WebSocketClientHandshakerFactory handshakerFactory, Supplier<ClientBootstrap> bootstrapSupplier, Executor resultExecutor) { this.address = address; this.port = port; this.handshakerFactory = handshakerFactory; this.bootstrapSupplier = bootstrapSupplier; this.resultExecutor = resultExecutor; } public RiemannPubSubConnection makeConnection(String query, boolean subscribe, QueryResultListener listener) throws InterruptedException, URISyntaxException { try { final String encodedQuery = URLEncoder.encode(query, Charsets.UTF_8.toString()); final String queryString = "query=" + encodedQuery + (subscribe ? "&subscribe=true" : ""); final URI uri = new URI("ws", "", address, port, "/index/", queryString, ""); final WebSocketClientHandshaker handshaker = handshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, false, null); final ClientBootstrap bootstrap = bootstrapSupplier.get(); final RiemannPubSubConnection connection = new RiemannPubSubConnection(resultExecutor, listener, bootstrap); bootstrap.setPipelineFactory(new WebSocketClientPipelineFactory(handshaker, connection)); final ChannelFuture connect = bootstrap.connect(new InetSocketAddress(uri.getHost(), uri.getPort())); connect.sync(); connection.init(connect.getChannel()); return connection; } catch (UnsupportedEncodingException e) { throw Throwables.propagate(e); } } public RiemannPubSubConnection makeConnection(String host, int port, String query, QueryResultListener listener) throws InterruptedException, URISyntaxException { return makeConnection(query, false, listener); } }