List of usage examples for com.google.common.util.concurrent ListenableFuture get
V get() throws InterruptedException, ExecutionException;
From source file:org.apache.druid.query.lookup.KafkaLookupExtractorFactory.java
@Override public boolean start() { synchronized (started) { if (started.get()) { LOG.warn("Already started, not starting again"); return started.get(); }//from www. jav a 2 s .c o m if (executorService.isShutdown()) { LOG.warn("Already shut down, not starting again"); return false; } final Properties kafkaProperties = new Properties(); kafkaProperties.putAll(getKafkaProperties()); if (kafkaProperties.containsKey("group.id")) { throw new IAE( "Cannot set kafka property [group.id]. Property is randomly generated for you. Found [%s]", kafkaProperties.getProperty("group.id")); } if (kafkaProperties.containsKey("auto.offset.reset")) { throw new IAE( "Cannot set kafka property [auto.offset.reset]. Property will be forced to [smallest]. Found [%s]", kafkaProperties.getProperty("auto.offset.reset")); } Preconditions.checkNotNull(kafkaProperties.getProperty("zookeeper.connect"), "zookeeper.connect required property"); kafkaProperties.setProperty("group.id", factoryId); final String topic = getKafkaTopic(); LOG.debug("About to listen to topic [%s] with group.id [%s]", topic, factoryId); cacheHandler = cacheManager.createCache(); final Map<String, String> map = cacheHandler.getCache(); mapRef.set(map); // Enable publish-subscribe kafkaProperties.setProperty("auto.offset.reset", "smallest"); final CountDownLatch startingReads = new CountDownLatch(1); final ListenableFuture<?> future = executorService.submit(new Runnable() { @Override public void run() { while (!executorService.isShutdown()) { consumerConnector = buildConnector(kafkaProperties); try { if (executorService.isShutdown()) { break; } final List<KafkaStream<String, String>> streams = consumerConnector .createMessageStreamsByFilter(new Whitelist(Pattern.quote(topic)), 1, DEFAULT_STRING_DECODER, DEFAULT_STRING_DECODER); if (streams == null || streams.isEmpty()) { throw new IAE("Topic [%s] had no streams", topic); } if (streams.size() > 1) { throw new ISE("Topic [%s] has %d streams! expected 1", topic, streams.size()); } final KafkaStream<String, String> kafkaStream = streams.get(0); startingReads.countDown(); for (final MessageAndMetadata<String, String> messageAndMetadata : kafkaStream) { final String key = messageAndMetadata.key(); final String message = messageAndMetadata.message(); if (key == null || message == null) { LOG.error("Bad key/message from topic [%s]: [%s]", topic, messageAndMetadata); continue; } doubleEventCount.incrementAndGet(); map.put(key, message); doubleEventCount.incrementAndGet(); LOG.trace("Placed key[%s] val[%s]", key, message); } } catch (Exception e) { LOG.error(e, "Error reading stream for topic [%s]", topic); } finally { consumerConnector.shutdown(); } } } }); Futures.addCallback(future, new FutureCallback<Object>() { @Override public void onSuccess(Object result) { LOG.debug("Success listening to [%s]", topic); } @Override public void onFailure(Throwable t) { if (t instanceof CancellationException) { LOG.debug("Topic [%s] cancelled", topic); } else { LOG.error(t, "Error in listening to [%s]", topic); } } }, MoreExecutors.sameThreadExecutor()); this.future = future; final Stopwatch stopwatch = Stopwatch.createStarted(); try { while (!startingReads.await(100, TimeUnit.MILLISECONDS) && connectTimeout > 0L) { // Don't return until we have actually connected if (future.isDone()) { future.get(); } else { if (stopwatch.elapsed(TimeUnit.MILLISECONDS) > connectTimeout) { throw new TimeoutException("Failed to connect to kafka in sufficient time"); } } } } catch (InterruptedException | ExecutionException | TimeoutException e) { executorService.shutdown(); if (!future.isDone() && !future.cancel(false)) { LOG.warn("Could not cancel kafka listening thread"); } LOG.error(e, "Failed to start kafka extraction factory"); cacheHandler.close(); return false; } started.set(true); return true; } }