/* * Copyright 2011 Future Systems * * 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. */ package org.krakenapps.logdb.client; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; import org.krakenapps.rpc.RpcClient; import org.krakenapps.rpc.RpcConnection; import org.krakenapps.rpc.RpcConnectionProperties; import org.krakenapps.rpc.RpcException; import org.krakenapps.rpc.RpcSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogDbClient { private final Logger logger = LoggerFactory.getLogger(LogDbClient.class.getName()); private String guid; private RpcClient client; private RpcSession session; private int bufferSize; private LogDbClientRpcService service; private Map<Integer, LogQueryStatus> queries; private List<Object> logs = new LinkedList<Object>(); public static void main(String[] args) throws RpcException, InterruptedException { final LogDbClient client = new LogDbClient("test-guid"); try { client.connect(new InetSocketAddress(7139), "1234"); LogQueryStatus q = client.createQuery("table test"); q.addCallback(new LogQueryCallback() { @Override public void onPageLoaded(int queryId) { } @Override public void onEof(int queryId) { try { LogQueryResult r = client.getResult(queryId, 0, 10); System.out.println("total " + r.getTotalCount()); Iterator<Object> it = r.getResult(); while (it.hasNext()) { @SuppressWarnings("unchecked") Map<String, Object> m = (Map<String, Object>) it.next(); System.out.println(m.get("_id") + ", " + m.get("line")); } client.removeQuery(queryId); } catch (Exception e) { e.printStackTrace(); } } }); System.out.println(q); client.startQuery(q.getId(), 0, 10, 5); client.waitFor(q.getId(), 5000); } finally { client.close(); } } public LogDbClient(String guid) { this.guid = guid; this.service = new LogDbClientRpcService(new RpcEventHandler()); this.queries = new ConcurrentHashMap<Integer, LogQueryStatus>(); } public int getBufferSize() { return bufferSize; } public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } public void connect(InetSocketAddress remote, String password) throws RpcException, InterruptedException { RpcConnectionProperties props = new RpcConnectionProperties(remote); props.setPassword(password); client = new RpcClient(guid); RpcConnection conn = client.connect(props); conn.bind("logdb-client", service); session = conn.createSession("logdb"); } public void connectSsl(InetSocketAddress remote, KeyManagerFactory kmf, TrustManagerFactory tmf) throws RpcException, InterruptedException { RpcConnectionProperties props = new RpcConnectionProperties(remote, kmf, tmf); client = new RpcClient(guid); RpcConnection conn = client.connect(props); conn.bind("logdb-client", service); session = conn.createSession("logdb"); } public void write(Log log) throws RpcException, InterruptedException { Map<String, Object> m = new HashMap<String, Object>(); m.put("table", log.getTableName()); m.put("date", log.getDate()); m.put("data", log.getData()); logs.add(m); if (logs.size() > bufferSize) flush(); } public LogQueryStatus createQuery(String query) throws RpcException, InterruptedException { int id = (Integer) session.call("createQuery", query); LogQueryStatus q = new LogQueryStatus(id, query, false); queries.put(id, q); return q; } public void startQuery(int queryId, int offset, int limit, int timelineSize) throws RpcException, InterruptedException { Map<String, Object> options = new HashMap<String, Object>(); options.put("id", queryId); options.put("offset", offset); options.put("limit", limit); options.put("timeline_size", timelineSize); session.call("startQuery", options); } public void removeQuery(int queryId) throws RpcException, InterruptedException { session.call("removeQuery", queryId); queries.remove(queryId); } public void waitFor(int queryId, int timeout) throws InterruptedException { Date begin = new Date(); while (true) { LogQueryStatus status = queries.get(queryId); if (status == null || status.isEnded()) break; Date now = new Date(); if (now.getTime() - begin.getTime() > timeout) throw new InterruptedException("timed out"); Thread.sleep(100); } } @SuppressWarnings("unchecked") public LogQueryResult getResult(int queryId, int offset, int limit) throws RpcException, InterruptedException { Map<String, Object> m = (Map<String, Object>) session.call("getResult", queryId, offset, limit); int totalCount = (Integer) m.get("count"); Object[] result = (Object[]) m.get("result"); return new LogQueryResult(offset, limit, totalCount, Arrays.asList(result)); } /** * flush logs * * @throws InterruptedException * @throws RpcException */ public void flush() throws RpcException, InterruptedException { if (logs.isEmpty()) return; if (logger.isTraceEnabled()) logger.trace("kraken logdb client: flushing {} logs", logs.size()); session.call("writeLogs", logs); logs.clear(); } public void createTable(String tableName) throws RpcException, InterruptedException { session.call("createTable", tableName, null); } public void dropTable(String tableName) throws RpcException, InterruptedException { session.call("dropTable", tableName); } public void close() throws RpcException, InterruptedException { try { flush(); } finally { client.close(); } } private class RpcEventHandler implements LogDbClientRpcCallback { @Override public void onPageLoaded(int queryId, int offset, int limit) { logger.info("kraken logdb client: on page loaded, id: {}, offset: {}, limit: {}", new Object[] { queryId, offset, limit }); LogQueryStatus status = queries.get(queryId); if (status == null) { logger.warn("kraken logdb client: query [{}] not found", queryId); return; } for (LogQueryCallback callback : status.getCallbacks()) callback.onPageLoaded(queryId); } @Override public void onEof(int queryId, int offset, int limit) { logger.info("kraken logdb client: on eof id: {}, offset: {}, limit: {}", new Object[] { queryId, offset, limit }); LogQueryStatus status = queries.get(queryId); if (status == null) { logger.warn("kraken logdb client: query [{}] not found", queryId); return; } status.setRunning(false); status.setEnded(true); for (LogQueryCallback callback : status.getCallbacks()) callback.onEof(queryId); } } }