@Override protected Map<String, String> exposeConfiguration() { final Map<String, String> properties = new LinkedHashMap<String, String>(super.exposeConfiguration()); properties.put(Config.LOCAL_FILE_SYSTEM_PATH, rootDir.getAbsolutePath()); return properties; }
@Override public synchronized Subject register(final String subjectName, final SubjectConfig config) { isValid(); Subject subject = subjectCache.lookup(subjectName); if (subject == null) { registerSubjectInBackend(subjectName, config); subject = getAndCacheSubject(subjectName); } else { logger.debug("Subject {} already exists, reusing", subjectName); } return subject; }
/** * Creates, applies validation decorator, and caches subject. * @param subjectName subject name * @return Subject the newly created instance or possibly pre-existing cached instance */ protected final Subject getAndCacheSubject(final String subjectName) { return cacheSubject(getSubjectInstance(subjectName)); }
@Override public synchronized Subject lookup(final String subjectName) { isValid(); Subject subject = subjectCache.lookup(subjectName); if (subject == null) { if (checkSubjectExistsInBackend(subjectName)) { subject = getAndCacheSubject(subjectName); } } return subject; }
@Override public synchronized Iterable<Subject> subjects() { isValid(); return subjectCache.values(); }
@Override public synchronized void close() { if (closed) { return; } try { fileLock.release(); } catch (IOException e) { // nothing to do here -- it was already released or there are underlying errors we cannot recover from logger.debug("Failed to release the lock {}", fileLock, e); } finally { closed = true; try { lockChannel.close(); } catch (IOException e) { // nothing to do here -- underlying errors but recovery not possible here or in client, and already closed logger.debug("Failed to close lockChannel {}", lockChannel, e); } } try { super.close(); } catch (IOException e) { // should never happen } }
@Override public synchronized Iterable<Subject> subjects() { isValid(); try { // TODO: Allow this behavior to be disabled once we have async updating // of the cache via ZK Observers... This would protect ZK from getting // hammered too much at the expense of slightly stale data. Iterable<String> subjectsInZk = zkClient.getChildren().forPath(""); for (String subjectInZk : subjectsInZk) { if (!subjectInZk.equals(LOCKFILE)) { if (subjectCache.lookup(subjectInZk) == null) { getAndCacheSubject(subjectInZk); } } } } catch (Exception e) { logger.error("An exception occurred while accessing ZK!", e); throw new RuntimeException(e); } return super.subjects(); }
@Override public synchronized Subject lookup(final String subjectName) { isValid(); Subject subject = subjectCache.lookup(subjectName); if (subject == null) { if (checkSubjectExistsInBackend(subjectName)) { subject = getAndCacheSubject(subjectName); } } return subject; }
@Override public synchronized Iterable<Subject> subjects() { isValid(); return subjectCache.values(); }
@Override public synchronized void close() { if (closed) { return; } try { fileLock.release(); } catch (IOException e) { // nothing to do here -- it was already released or there are underlying errors we cannot recover from logger.debug("Failed to release the lock {}", fileLock, e); } finally { closed = true; try { lockChannel.close(); } catch (IOException e) { // nothing to do here -- underlying errors but recovery not possible here or in client, and already closed logger.debug("Failed to close lockChannel {}", lockChannel, e); } } try { super.close(); } catch (IOException e) { // should never happen } }
@Override public synchronized Subject register(final String subjectName, final SubjectConfig config) { isValid(); Subject subject = subjectCache.lookup(subjectName); if (subject == null) { registerSubjectInBackend(subjectName, config); subject = getAndCacheSubject(subjectName); } else { logger.debug("Subject {} already exists, reusing", subjectName); } return subject; }
@Override protected Map<String, String> exposeConfiguration() { final Map<String, String> properties = new LinkedHashMap<String, String>(super.exposeConfiguration()); properties.put(Config.LOCAL_FILE_SYSTEM_PATH, rootDir.getAbsolutePath()); return properties; }
@Override public void isValid() { super.isValid(); if (zkClient.getState() != CuratorFrameworkState.STARTED) { throw new IllegalStateException("ZK Client is not connected"); } }
/** * Closes this stream and releases any system resources associated * with it. If the stream is already closed then invoking this * method has no effect. * * @throws java.io.IOException if an I/O error occurs */ @Override public void close() throws IOException { Integer waitTime = 100; while (true) { if (zkLock.isAcquiredInThisProcess()) { try { logger.info("ZooKeeperRepository's close() called while lock is acquired. " + "Waiting " + waitTime + " ms before trying again."); wait(waitTime); } catch (InterruptedException e) { logger.warn("Interrupted while waiting", e); } } else { // TODO: Make sure the race condition between the if condition and the close is harmless... zkClient.close(); break; } } closed = true; super.close(); }
/** * Creates, applies validation decorator, and caches subject. * @param subjectName subject name * @return Subject the newly created instance or possibly pre-existing cached instance */ protected final Subject getAndCacheSubject(final String subjectName) { return cacheSubject(getSubjectInstance(subjectName)); }
@Override protected Map<String, String> exposeConfiguration() { final Map<String, String> properties = new LinkedHashMap<String, String>(super.exposeConfiguration()); properties.put(Config.ZK_ENSEMBLE, zkClient.getZookeeperClient().getCurrentConnectionString()); return properties; }