pax_global_header 0000666 0000000 0000000 00000000064 12455216776 0014531 g ustar 00root root 0000000 0000000 52 comment=09e9a55c94bd52bab712a546f90e6390584f209a
curator-apache-curator-2.7.1/ 0000775 0000000 0000000 00000000000 12455216776 0016113 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/.gitignore 0000664 0000000 0000000 00000001375 12455216776 0020111 0 ustar 00root root 0000000 0000000 # Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
# OS generated files #
######################
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db
# Editor Files #
################
*~
*.swp
# Gradle Files #
################
.gradle
# Build output directies
/target
*/target
/build
*/build
*/bin
# IntelliJ specific files/directories
out
.idea
*.ipr
*.iws
*.iml
atlassian-ide-plugin.xml
# Eclipse specific files/directories
.classpath
.project
.settings
.metadata
# NetBeans specific files/directories
.nbattrs
curator-apache-curator-2.7.1/DEPENDENCIES 0000664 0000000 0000000 00000000035 12455216776 0017662 0 ustar 00root root 0000000 0000000 * intentionally left blank *
curator-apache-curator-2.7.1/LICENSE 0000664 0000000 0000000 00000026136 12455216776 0017130 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
curator-apache-curator-2.7.1/NOTICE 0000664 0000000 0000000 00000000250 12455216776 0017014 0 ustar 00root root 0000000 0000000 Apache Curator
Copyright 2013-2014 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
curator-apache-curator-2.7.1/README 0000664 0000000 0000000 00000000325 12455216776 0016773 0 ustar 00root root 0000000 0000000 Apache Curator
--------------
Curator is a set of Java libraries that make using Apache ZooKeeper much easier.
Website: http://curator.apache.org/
Getting started: http://curator.apache.org/getting-started.html
curator-apache-curator-2.7.1/curator-client/ 0000775 0000000 0000000 00000000000 12455216776 0021046 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/LICENSE 0000664 0000000 0000000 00000026136 12455216776 0022063 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
curator-apache-curator-2.7.1/curator-client/NOTICE 0000664 0000000 0000000 00000000250 12455216776 0021747 0 ustar 00root root 0000000 0000000 Apache Curator
Copyright 2013-2014 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
curator-apache-curator-2.7.1/curator-client/pom.xml 0000664 0000000 0000000 00000004324 12455216776 0022366 0 ustar 00root root 0000000 0000000
4.0.0org.apache.curatorapache-curator2.7.1curator-client2.7.1bundleCurator ClientLow-level API2011
*
org.apache.curator*;version="${project.version}";-noimport:=true
org.slf4jslf4j-apiorg.mockitomockito-coretestorg.apache.curatorcurator-testtest
curator-apache-curator-2.7.1/curator-client/src/ 0000775 0000000 0000000 00000000000 12455216776 0021635 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/ 0000775 0000000 0000000 00000000000 12455216776 0022561 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/ 0000775 0000000 0000000 00000000000 12455216776 0023502 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/ 0000775 0000000 0000000 00000000000 12455216776 0024271 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/ 0000775 0000000 0000000 00000000000 12455216776 0025512 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ 0000775 0000000 0000000 00000000000 12455216776 0027171 5 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ConnectionState.java 0000664 0000000 0000000 00000022356 12455216776 0033144 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import org.apache.curator.utils.CloseableUtils;
import org.apache.curator.drivers.TracerDriver;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.utils.DebugUtils;
import org.apache.curator.utils.ZookeeperFactory;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
class ConnectionState implements Watcher, Closeable
{
private static final int MAX_BACKGROUND_EXCEPTIONS = 10;
private static final boolean LOG_EVENTS = Boolean.getBoolean(DebugUtils.PROPERTY_LOG_EVENTS);
private final Logger log = LoggerFactory.getLogger(getClass());
private final HandleHolder zooKeeper;
private final AtomicBoolean isConnected = new AtomicBoolean(false);
private final EnsembleProvider ensembleProvider;
private final int sessionTimeoutMs;
private final int connectionTimeoutMs;
private final AtomicReference tracer;
private final Queue backgroundExceptions = new ConcurrentLinkedQueue();
private final Queue parentWatchers = new ConcurrentLinkedQueue();
private final AtomicLong instanceIndex = new AtomicLong();
private volatile long connectionStartMs = 0;
ConnectionState(ZookeeperFactory zookeeperFactory, EnsembleProvider ensembleProvider, int sessionTimeoutMs, int connectionTimeoutMs, Watcher parentWatcher, AtomicReference tracer, boolean canBeReadOnly)
{
this.ensembleProvider = ensembleProvider;
this.sessionTimeoutMs = sessionTimeoutMs;
this.connectionTimeoutMs = connectionTimeoutMs;
this.tracer = tracer;
if ( parentWatcher != null )
{
parentWatchers.offer(parentWatcher);
}
zooKeeper = new HandleHolder(zookeeperFactory, this, ensembleProvider, sessionTimeoutMs, canBeReadOnly);
}
ZooKeeper getZooKeeper() throws Exception
{
if ( SessionFailRetryLoop.sessionForThreadHasFailed() )
{
throw new SessionFailRetryLoop.SessionFailedException();
}
Exception exception = backgroundExceptions.poll();
if ( exception != null )
{
tracer.get().addCount("background-exceptions", 1);
throw exception;
}
boolean localIsConnected = isConnected.get();
if ( !localIsConnected )
{
checkTimeouts();
}
return zooKeeper.getZooKeeper();
}
boolean isConnected()
{
return isConnected.get();
}
void start() throws Exception
{
log.debug("Starting");
ensembleProvider.start();
reset();
}
@Override
public void close() throws IOException
{
log.debug("Closing");
CloseableUtils.closeQuietly(ensembleProvider);
try
{
zooKeeper.closeAndClear();
}
catch ( Exception e )
{
throw new IOException(e);
}
finally
{
isConnected.set(false);
}
}
void addParentWatcher(Watcher watcher)
{
parentWatchers.offer(watcher);
}
void removeParentWatcher(Watcher watcher)
{
parentWatchers.remove(watcher);
}
long getInstanceIndex()
{
return instanceIndex.get();
}
@Override
public void process(WatchedEvent event)
{
if ( LOG_EVENTS )
{
log.debug("ConnectState watcher: " + event);
}
for ( Watcher parentWatcher : parentWatchers )
{
TimeTrace timeTrace = new TimeTrace("connection-state-parent-process", tracer.get());
parentWatcher.process(event);
timeTrace.commit();
}
boolean wasConnected = isConnected.get();
boolean newIsConnected = wasConnected;
if ( event.getType() == Watcher.Event.EventType.None )
{
newIsConnected = checkState(event.getState(), wasConnected);
}
if ( newIsConnected != wasConnected )
{
isConnected.set(newIsConnected);
connectionStartMs = System.currentTimeMillis();
}
}
EnsembleProvider getEnsembleProvider()
{
return ensembleProvider;
}
private synchronized void checkTimeouts() throws Exception
{
int minTimeout = Math.min(sessionTimeoutMs, connectionTimeoutMs);
long elapsed = System.currentTimeMillis() - connectionStartMs;
if ( elapsed >= minTimeout )
{
if ( zooKeeper.hasNewConnectionString() )
{
handleNewConnectionString();
}
else
{
int maxTimeout = Math.max(sessionTimeoutMs, connectionTimeoutMs);
if ( elapsed > maxTimeout )
{
if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
{
log.warn(String.format("Connection attempt unsuccessful after %d (greater than max timeout of %d). Resetting connection and trying again with a new connection.", elapsed, maxTimeout));
}
reset();
}
else
{
KeeperException.ConnectionLossException connectionLossException = new CuratorConnectionLossException();
if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
{
log.error(String.format("Connection timed out for connection string (%s) and timeout (%d) / elapsed (%d)", zooKeeper.getConnectionString(), connectionTimeoutMs, elapsed), connectionLossException);
}
tracer.get().addCount("connections-timed-out", 1);
throw connectionLossException;
}
}
}
}
private synchronized void reset() throws Exception
{
log.debug("reset");
instanceIndex.incrementAndGet();
isConnected.set(false);
connectionStartMs = System.currentTimeMillis();
zooKeeper.closeAndReset();
zooKeeper.getZooKeeper(); // initiate connection
}
private boolean checkState(Event.KeeperState state, boolean wasConnected)
{
boolean isConnected = wasConnected;
boolean checkNewConnectionString = true;
switch ( state )
{
default:
case Disconnected:
{
isConnected = false;
break;
}
case SyncConnected:
case ConnectedReadOnly:
{
isConnected = true;
break;
}
case AuthFailed:
{
isConnected = false;
log.error("Authentication failed");
break;
}
case Expired:
{
isConnected = false;
checkNewConnectionString = false;
handleExpiredSession();
break;
}
case SaslAuthenticated:
{
// NOP
break;
}
}
if ( checkNewConnectionString && zooKeeper.hasNewConnectionString() )
{
handleNewConnectionString();
}
return isConnected;
}
private void handleNewConnectionString()
{
log.info("Connection string changed");
tracer.get().addCount("connection-string-changed", 1);
try
{
reset();
}
catch ( Exception e )
{
queueBackgroundException(e);
}
}
private void handleExpiredSession()
{
log.warn("Session expired event received");
tracer.get().addCount("session-expired", 1);
try
{
reset();
}
catch ( Exception e )
{
queueBackgroundException(e);
}
}
@SuppressWarnings({"ThrowableResultOfMethodCallIgnored"})
private void queueBackgroundException(Exception e)
{
while ( backgroundExceptions.size() >= MAX_BACKGROUND_EXCEPTIONS )
{
backgroundExceptions.poll();
}
backgroundExceptions.offer(e);
}
}
CuratorConnectionLossException.java 0000664 0000000 0000000 00000002267 12455216776 0036143 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import org.apache.zookeeper.KeeperException;
/**
* This is needed to differentiate between ConnectionLossException thrown by ZooKeeper
* and ConnectionLossException thrown by {@link ConnectionState#checkTimeouts()}
*/
public class CuratorConnectionLossException extends KeeperException.ConnectionLossException
{
private static final long serialVersionUID = 1L;
}
CuratorZookeeperClient.java 0000664 0000000 0000000 00000025067 12455216776 0034431 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import com.google.common.base.Preconditions;
import org.apache.curator.drivers.TracerDriver;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.ensemble.fixed.FixedEnsembleProvider;
import org.apache.curator.utils.DefaultTracerDriver;
import org.apache.curator.utils.DefaultZookeeperFactory;
import org.apache.curator.utils.ZookeeperFactory;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
/**
* A wrapper around Zookeeper that takes care of some low-level housekeeping
*/
@SuppressWarnings("UnusedDeclaration")
public class CuratorZookeeperClient implements Closeable
{
private final Logger log = LoggerFactory.getLogger(getClass());
private final ConnectionState state;
private final AtomicReference retryPolicy = new AtomicReference();
private final int connectionTimeoutMs;
private final AtomicBoolean started = new AtomicBoolean(false);
private final AtomicReference tracer = new AtomicReference(new DefaultTracerDriver());
/**
*
* @param connectString list of servers to connect to
* @param sessionTimeoutMs session timeout
* @param connectionTimeoutMs connection timeout
* @param watcher default watcher or null
* @param retryPolicy the retry policy to use
*/
public CuratorZookeeperClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, Watcher watcher, RetryPolicy retryPolicy)
{
this(new DefaultZookeeperFactory(), new FixedEnsembleProvider(connectString), sessionTimeoutMs, connectionTimeoutMs, watcher, retryPolicy, false);
}
/**
* @param ensembleProvider the ensemble provider
* @param sessionTimeoutMs session timeout
* @param connectionTimeoutMs connection timeout
* @param watcher default watcher or null
* @param retryPolicy the retry policy to use
*/
public CuratorZookeeperClient(EnsembleProvider ensembleProvider, int sessionTimeoutMs, int connectionTimeoutMs, Watcher watcher, RetryPolicy retryPolicy)
{
this(new DefaultZookeeperFactory(), ensembleProvider, sessionTimeoutMs, connectionTimeoutMs, watcher, retryPolicy, false);
}
/**
* @param zookeeperFactory factory for creating {@link ZooKeeper} instances
* @param ensembleProvider the ensemble provider
* @param sessionTimeoutMs session timeout
* @param connectionTimeoutMs connection timeout
* @param watcher default watcher or null
* @param retryPolicy the retry policy to use
* @param canBeReadOnly if true, allow ZooKeeper client to enter
* read only mode in case of a network partition. See
* {@link ZooKeeper#ZooKeeper(String, int, Watcher, long, byte[], boolean)}
* for details
*/
public CuratorZookeeperClient(ZookeeperFactory zookeeperFactory, EnsembleProvider ensembleProvider, int sessionTimeoutMs, int connectionTimeoutMs, Watcher watcher, RetryPolicy retryPolicy, boolean canBeReadOnly)
{
if ( sessionTimeoutMs < connectionTimeoutMs )
{
log.warn(String.format("session timeout [%d] is less than connection timeout [%d]", sessionTimeoutMs, connectionTimeoutMs));
}
retryPolicy = Preconditions.checkNotNull(retryPolicy, "retryPolicy cannot be null");
ensembleProvider = Preconditions.checkNotNull(ensembleProvider, "ensembleProvider cannot be null");
this.connectionTimeoutMs = connectionTimeoutMs;
state = new ConnectionState(zookeeperFactory, ensembleProvider, sessionTimeoutMs, connectionTimeoutMs, watcher, tracer, canBeReadOnly);
setRetryPolicy(retryPolicy);
}
/**
* Return the managed ZK instance.
*
* @return client the client
* @throws Exception if the connection timeout has elapsed or an exception occurs in a background process
*/
public ZooKeeper getZooKeeper() throws Exception
{
Preconditions.checkState(started.get(), "Client is not started");
return state.getZooKeeper();
}
/**
* Return a new retry loop. All operations should be performed in a retry loop
*
* @return new retry loop
*/
public RetryLoop newRetryLoop()
{
return new RetryLoop(retryPolicy.get(), tracer);
}
/**
* Return a new "session fail" retry loop. See {@link SessionFailRetryLoop} for details
* on when to use it.
*
* @param mode failure mode
* @return new retry loop
*/
public SessionFailRetryLoop newSessionFailRetryLoop(SessionFailRetryLoop.Mode mode)
{
return new SessionFailRetryLoop(this, mode);
}
/**
* Returns true if the client is current connected
*
* @return true/false
*/
public boolean isConnected()
{
return state.isConnected();
}
/**
* This method blocks until the connection to ZK succeeds. Use with caution. The block
* will timeout after the connection timeout (as passed to the constructor) has elapsed
*
* @return true if the connection succeeded, false if not
* @throws InterruptedException interrupted while waiting
*/
public boolean blockUntilConnectedOrTimedOut() throws InterruptedException
{
Preconditions.checkState(started.get(), "Client is not started");
log.debug("blockUntilConnectedOrTimedOut() start");
TimeTrace trace = startTracer("blockUntilConnectedOrTimedOut");
internalBlockUntilConnectedOrTimedOut();
trace.commit();
boolean localIsConnected = state.isConnected();
log.debug("blockUntilConnectedOrTimedOut() end. isConnected: " + localIsConnected);
return localIsConnected;
}
/**
* Must be called after construction
*
* @throws IOException errors
*/
public void start() throws Exception
{
log.debug("Starting");
if ( !started.compareAndSet(false, true) )
{
IllegalStateException ise = new IllegalStateException("Already started");
throw ise;
}
state.start();
}
/**
* Close the client
*/
public void close()
{
log.debug("Closing");
started.set(false);
try
{
state.close();
}
catch ( IOException e )
{
log.error("", e);
}
}
/**
* Change the retry policy
*
* @param policy new policy
*/
public void setRetryPolicy(RetryPolicy policy)
{
Preconditions.checkNotNull(policy, "policy cannot be null");
retryPolicy.set(policy);
}
/**
* Return the current retry policy
*
* @return policy
*/
public RetryPolicy getRetryPolicy()
{
return retryPolicy.get();
}
/**
* Start a new tracer
* @param name name of the event
* @return the new tracer ({@link TimeTrace#commit()} must be called)
*/
public TimeTrace startTracer(String name)
{
return new TimeTrace(name, tracer.get());
}
/**
* Return the current tracing driver
*
* @return tracing driver
*/
public TracerDriver getTracerDriver()
{
return tracer.get();
}
/**
* Change the tracing driver
*
* @param tracer new tracing driver
*/
public void setTracerDriver(TracerDriver tracer)
{
this.tracer.set(tracer);
}
/**
* Returns the current known connection string - not guaranteed to be correct
* value at any point in the future.
*
* @return connection string
*/
public String getCurrentConnectionString()
{
return state.getEnsembleProvider().getConnectionString();
}
/**
* Return the configured connection timeout
*
* @return timeout
*/
public int getConnectionTimeoutMs()
{
return connectionTimeoutMs;
}
/**
* Every time a new {@link ZooKeeper} instance is allocated, the "instance index"
* is incremented.
*
* @return the current instance index
*/
public long getInstanceIndex()
{
return state.getInstanceIndex();
}
void addParentWatcher(Watcher watcher)
{
state.addParentWatcher(watcher);
}
void removeParentWatcher(Watcher watcher)
{
state.removeParentWatcher(watcher);
}
void internalBlockUntilConnectedOrTimedOut() throws InterruptedException
{
long waitTimeMs = connectionTimeoutMs;
while ( !state.isConnected() && (waitTimeMs > 0) )
{
final CountDownLatch latch = new CountDownLatch(1);
Watcher tempWatcher = new Watcher()
{
@Override
public void process(WatchedEvent event)
{
latch.countDown();
}
};
state.addParentWatcher(tempWatcher);
long startTimeMs = System.currentTimeMillis();
try
{
latch.await(1, TimeUnit.SECONDS);
}
finally
{
state.removeParentWatcher(tempWatcher);
}
long elapsed = Math.max(1, System.currentTimeMillis() - startTimeMs);
waitTimeMs -= elapsed;
}
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/HandleHolder.java 0000664 0000000 0000000 00000011242 12455216776 0032365 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.utils.ZookeeperFactory;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
class HandleHolder
{
private final ZookeeperFactory zookeeperFactory;
private final Watcher watcher;
private final EnsembleProvider ensembleProvider;
private final int sessionTimeout;
private final boolean canBeReadOnly;
private volatile Helper helper;
private interface Helper
{
ZooKeeper getZooKeeper() throws Exception;
String getConnectionString();
}
HandleHolder(ZookeeperFactory zookeeperFactory, Watcher watcher, EnsembleProvider ensembleProvider, int sessionTimeout, boolean canBeReadOnly)
{
this.zookeeperFactory = zookeeperFactory;
this.watcher = watcher;
this.ensembleProvider = ensembleProvider;
this.sessionTimeout = sessionTimeout;
this.canBeReadOnly = canBeReadOnly;
}
ZooKeeper getZooKeeper() throws Exception
{
return (helper != null) ? helper.getZooKeeper() : null;
}
String getConnectionString()
{
return (helper != null) ? helper.getConnectionString() : null;
}
boolean hasNewConnectionString()
{
String helperConnectionString = (helper != null) ? helper.getConnectionString() : null;
return (helperConnectionString != null) && !ensembleProvider.getConnectionString().equals(helperConnectionString);
}
void closeAndClear() throws Exception
{
internalClose();
helper = null;
}
void closeAndReset() throws Exception
{
internalClose();
// first helper is synchronized when getZooKeeper is called. Subsequent calls
// are not synchronized.
helper = new Helper()
{
private volatile ZooKeeper zooKeeperHandle = null;
private volatile String connectionString = null;
@Override
public ZooKeeper getZooKeeper() throws Exception
{
synchronized(this)
{
if ( zooKeeperHandle == null )
{
connectionString = ensembleProvider.getConnectionString();
zooKeeperHandle = zookeeperFactory.newZooKeeper(connectionString, sessionTimeout, watcher, canBeReadOnly);
}
helper = new Helper()
{
@Override
public ZooKeeper getZooKeeper() throws Exception
{
return zooKeeperHandle;
}
@Override
public String getConnectionString()
{
return connectionString;
}
};
return zooKeeperHandle;
}
}
@Override
public String getConnectionString()
{
return connectionString;
}
};
}
private void internalClose() throws Exception
{
try
{
ZooKeeper zooKeeper = (helper != null) ? helper.getZooKeeper() : null;
if ( zooKeeper != null )
{
Watcher dummyWatcher = new Watcher()
{
@Override
public void process(WatchedEvent event)
{
}
};
zooKeeper.register(dummyWatcher); // clear the default watcher so that no new events get processed by mistake
zooKeeper.close();
}
}
catch ( InterruptedException dummy )
{
Thread.currentThread().interrupt();
}
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/RetryLoop.java 0000664 0000000 0000000 00000014570 12455216776 0032002 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import org.apache.curator.drivers.TracerDriver;
import org.apache.curator.utils.DebugUtils;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
*
Mechanism to perform an operation on Zookeeper that is safe against
* disconnections and "recoverable" errors.
*
*
* If an exception occurs during the operation, the RetryLoop will process it,
* check with the current retry policy and either attempt to reconnect or re-throw
* the exception
*
*
* Canonical usage:
*
* RetryLoop retryLoop = client.newRetryLoop();
* while ( retryLoop.shouldContinue() )
* {
* try
* {
* // do your work
* ZooKeeper zk = client.getZooKeeper(); // it's important to re-get the ZK instance in case there was an error and the instance was re-created
*
* retryLoop.markComplete();
* }
* catch ( Exception e )
* {
* retryLoop.takeException(e);
* }
* }
*
*/
public class RetryLoop
{
private boolean isDone = false;
private int retryCount = 0;
private final Logger log = LoggerFactory.getLogger(getClass());
private final long startTimeMs = System.currentTimeMillis();
private final RetryPolicy retryPolicy;
private final AtomicReference tracer;
private static final RetrySleeper sleeper = new RetrySleeper()
{
@Override
public void sleepFor(long time, TimeUnit unit) throws InterruptedException
{
unit.sleep(time);
}
};
/**
* Returns the default retry sleeper
*
* @return sleeper
*/
public static RetrySleeper getDefaultRetrySleeper()
{
return sleeper;
}
/**
* Convenience utility: creates a retry loop calling the given proc and retrying if needed
*
* @param client Zookeeper
* @param proc procedure to call with retry
* @param return type
* @return procedure result
* @throws Exception any non-retriable errors
*/
public static T callWithRetry(CuratorZookeeperClient client, Callable proc) throws Exception
{
T result = null;
RetryLoop retryLoop = client.newRetryLoop();
while ( retryLoop.shouldContinue() )
{
try
{
client.internalBlockUntilConnectedOrTimedOut();
result = proc.call();
retryLoop.markComplete();
}
catch ( Exception e )
{
retryLoop.takeException(e);
}
}
return result;
}
RetryLoop(RetryPolicy retryPolicy, AtomicReference tracer)
{
this.retryPolicy = retryPolicy;
this.tracer = tracer;
}
/**
* If true is returned, make an attempt at the operation
*
* @return true/false
*/
public boolean shouldContinue()
{
return !isDone;
}
/**
* Call this when your operation has successfully completed
*/
public void markComplete()
{
isDone = true;
}
/**
* Utility - return true if the given Zookeeper result code is retry-able
*
* @param rc result code
* @return true/false
*/
public static boolean shouldRetry(int rc)
{
return (rc == KeeperException.Code.CONNECTIONLOSS.intValue()) ||
(rc == KeeperException.Code.OPERATIONTIMEOUT.intValue()) ||
(rc == KeeperException.Code.SESSIONMOVED.intValue()) ||
(rc == KeeperException.Code.SESSIONEXPIRED.intValue());
}
/**
* Utility - return true if the given exception is retry-able
*
* @param exception exception to check
* @return true/false
*/
public static boolean isRetryException(Throwable exception)
{
if ( exception instanceof KeeperException )
{
KeeperException keeperException = (KeeperException)exception;
return shouldRetry(keeperException.code().intValue());
}
return false;
}
/**
* Pass any caught exceptions here
*
* @param exception the exception
* @throws Exception if not retry-able or the retry policy returned negative
*/
public void takeException(Exception exception) throws Exception
{
boolean rethrow = true;
if ( isRetryException(exception) )
{
if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
{
log.debug("Retry-able exception received", exception);
}
if ( retryPolicy.allowRetry(retryCount++, System.currentTimeMillis() - startTimeMs, sleeper) )
{
tracer.get().addCount("retries-allowed", 1);
if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
{
log.debug("Retrying operation");
}
rethrow = false;
}
else
{
tracer.get().addCount("retries-disallowed", 1);
if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
{
log.debug("Retry policy not allowing retry");
}
}
}
if ( rethrow )
{
throw exception;
}
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/RetryPolicy.java 0000664 0000000 0000000 00000002640 12455216776 0032323 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
/**
* Abstracts the policy to use when retrying connections
*/
public interface RetryPolicy
{
/**
* Called when an operation has failed for some reason. This method should return
* true to make another attempt.
*
*
* @param retryCount the number of times retried so far (0 the first time)
* @param elapsedTimeMs the elapsed time in ms since the operation was attempted
* @param sleeper use this to sleep - DO NOT call Thread.sleep
* @return true/false
*/
public boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper);
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/RetrySleeper.java 0000664 0000000 0000000 00000002302 12455216776 0032456 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import java.util.concurrent.TimeUnit;
/**
* Abstraction for retry policies to sleep
*/
public interface RetrySleeper
{
/**
* Sleep for the given time
*
* @param time time
* @param unit time unit
* @throws InterruptedException if the sleep is interrupted
*/
public void sleepFor(long time, TimeUnit unit) throws InterruptedException;
}
SessionFailRetryLoop.java 0000664 0000000 0000000 00000017747 12455216776 0034074 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import java.io.Closeable;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
/**
*
* See {@link RetryLoop} for the main details on retry loops. All Curator/ZooKeeper operations
* should be done in a retry loop.
*
*
*
* The standard retry loop treats session failure as a type of connection failure. i.e. the fact
* that it is a session failure isn't considered. This can be problematic if you are performing
* a series of operations that rely on ephemeral nodes. If the session fails after the ephemeral
* node has been created, future Curator/ZooKeeper operations may succeed even though the
* ephemeral node has been removed by ZooKeeper.
*
*
*
* Here's an example:
*
*
*
You create an ephemeral/sequential node as a kind of lock/marker
*
You perform some other operations
*
The session fails for some reason
*
You attempt to create a node assuming that the lock/marker still exists
*
*
Curator will notice the session failure and try to reconnect
*
In most cases, the reconnect will succeed and, thus, the node creation will succeed
* even though the ephemeral node will have been deleted by ZooKeeper.
*
*
*
*
*
* The SessionFailRetryLoop prevents this type of scenario. When a session failure is detected,
* the thread is marked as failed which will cause all future Curator operations to fail. The
* SessionFailRetryLoop will then either retry the entire
* set of operations or fail (depending on {@link SessionFailRetryLoop.Mode})
*
*/
public class SessionFailRetryLoop implements Closeable
{
private final CuratorZookeeperClient client;
private final Mode mode;
private final Thread ourThread = Thread.currentThread();
private final AtomicBoolean sessionHasFailed = new AtomicBoolean(false);
private final AtomicBoolean isDone = new AtomicBoolean(false);
private final RetryLoop retryLoop;
private final Watcher watcher = new Watcher()
{
@Override
public void process(WatchedEvent event)
{
if ( event.getState() == Event.KeeperState.Expired )
{
sessionHasFailed.set(true);
failedSessionThreads.add(ourThread);
}
}
};
private static final Set failedSessionThreads = Sets.newSetFromMap(Maps.newConcurrentMap());
public static class SessionFailedException extends Exception
{
private static final long serialVersionUID = 1L;
}
public enum Mode
{
/**
* If the session fails, retry the entire set of operations when {@link SessionFailRetryLoop#shouldContinue()}
* is called
*/
RETRY,
/**
* If the session fails, throw {@link KeeperException.SessionExpiredException} when
* {@link SessionFailRetryLoop#shouldContinue()} is called
*/
FAIL
}
/**
* Convenience utility: creates a "session fail" retry loop calling the given proc
*
* @param client Zookeeper
* @param mode how to handle session failures
* @param proc procedure to call with retry
* @param return type
* @return procedure result
* @throws Exception any non-retriable errors
*/
public static T callWithRetry(CuratorZookeeperClient client, Mode mode, Callable proc) throws Exception
{
T result = null;
SessionFailRetryLoop retryLoop = client.newSessionFailRetryLoop(mode);
retryLoop.start();
try
{
while ( retryLoop.shouldContinue() )
{
try
{
result = proc.call();
}
catch ( Exception e )
{
retryLoop.takeException(e);
}
}
}
finally
{
retryLoop.close();
}
return result;
}
SessionFailRetryLoop(CuratorZookeeperClient client, Mode mode)
{
this.client = client;
this.mode = mode;
retryLoop = client.newRetryLoop();
}
static boolean sessionForThreadHasFailed()
{
return (failedSessionThreads.size() > 0) && failedSessionThreads.contains(Thread.currentThread());
}
/**
* SessionFailRetryLoop must be started
*/
public void start()
{
Preconditions.checkState(Thread.currentThread().equals(ourThread), "Not in the correct thread");
client.addParentWatcher(watcher);
}
/**
* If true is returned, make an attempt at the set of operations
*
* @return true/false
*/
public boolean shouldContinue()
{
boolean localIsDone = isDone.getAndSet(true);
return !localIsDone;
}
/**
* Must be called in a finally handler when done with the loop
*/
@Override
public void close()
{
Preconditions.checkState(Thread.currentThread().equals(ourThread), "Not in the correct thread");
failedSessionThreads.remove(ourThread);
client.removeParentWatcher(watcher);
}
/**
* Pass any caught exceptions here
*
* @param exception the exception
* @throws Exception if not retry-able or the retry policy returned negative
*/
public void takeException(Exception exception) throws Exception
{
Preconditions.checkState(Thread.currentThread().equals(ourThread), "Not in the correct thread");
boolean passUp = true;
if ( sessionHasFailed.get() )
{
switch ( mode )
{
case RETRY:
{
sessionHasFailed.set(false);
failedSessionThreads.remove(ourThread);
if ( exception instanceof SessionFailedException )
{
isDone.set(false);
passUp = false;
}
break;
}
case FAIL:
{
break;
}
}
}
if ( passUp )
{
retryLoop.takeException(exception);
}
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/TimeTrace.java 0000664 0000000 0000000 00000003071 12455216776 0031712 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator;
import org.apache.curator.drivers.TracerDriver;
import java.util.concurrent.TimeUnit;
/**
* Utility to time a method or portion of code
*/
public class TimeTrace
{
private final String name;
private final TracerDriver driver;
private final long startTimeNanos = System.nanoTime();
/**
* Create and start a timer
*
* @param name name of the event
* @param driver driver
*/
public TimeTrace(String name, TracerDriver driver)
{
this.name = name;
this.driver = driver;
}
/**
* Record the elapsed time
*/
public void commit()
{
long elapsed = System.nanoTime() - startTimeNanos;
driver.addTrace(name, elapsed, TimeUnit.NANOSECONDS);
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/drivers/ 0000775 0000000 0000000 00000000000 12455216776 0030647 5 ustar 00root root 0000000 0000000 TracerDriver.java 0000664 0000000 0000000 00000002571 12455216776 0034034 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/drivers /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.drivers;
import java.util.concurrent.TimeUnit;
/**
* Mechanism for timing methods and recording counters
*/
public interface TracerDriver
{
/**
* Record the given trace event
*
* @param name of the event
* @param time time event took
* @param unit time unit
*/
public void addTrace(String name, long time, TimeUnit unit);
/**
* Add to a named counter
*
* @param name name of the counter
* @param increment amount to increment
*/
public void addCount(String name, int increment);
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/ 0000775 0000000 0000000 00000000000 12455216776 0030763 5 ustar 00root root 0000000 0000000 EnsembleProvider.java 0000664 0000000 0000000 00000003501 12455216776 0035013 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.ensemble;
import org.apache.curator.CuratorZookeeperClient;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.io.Closeable;
import java.io.IOException;
/**
* Abstraction that provides the ZooKeeper connection string
*/
public interface EnsembleProvider extends Closeable
{
/**
* Curator will call this method when {@link CuratorZookeeperClient#start()} is
* called
*
* @throws Exception errors
*/
public void start() throws Exception;
/**
* Return the current connection string to use. Curator will call this each
* time it needs to create a ZooKeeper instance
*
* @return connection string (per {@link ZooKeeper#ZooKeeper(String, int, Watcher)} etc.)
*/
public String getConnectionString();
/**
* Curator will call this method when {@link CuratorZookeeperClient#close()} is called
*
* @throws IOException errors
*/
public void close() throws IOException;
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/exhibitor/ 0000775 0000000 0000000 00000000000 12455216776 0032760 5 ustar 00root root 0000000 0000000 DefaultExhibitorRestClient.java 0000664 0000000 0000000 00000004307 12455216776 0041007 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/exhibitor /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.ensemble.exhibitor;
import org.apache.curator.utils.CloseableUtils;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
@SuppressWarnings("UnusedDeclaration")
public class DefaultExhibitorRestClient implements ExhibitorRestClient
{
private final boolean useSsl;
public DefaultExhibitorRestClient()
{
this(false);
}
public DefaultExhibitorRestClient(boolean useSsl)
{
this.useSsl = useSsl;
}
@Override
public String getRaw(String hostname, int port, String uriPath, String mimeType) throws Exception
{
URI uri = new URI(useSsl ? "https" : "http", null, hostname, port, uriPath, null, null);
HttpURLConnection connection = (HttpURLConnection)uri.toURL().openConnection();
connection.addRequestProperty("Accept", mimeType);
StringBuilder str = new StringBuilder();
InputStream in = new BufferedInputStream(connection.getInputStream());
try
{
for(;;)
{
int b = in.read();
if ( b < 0 )
{
break;
}
str.append((char)(b & 0xff));
}
}
finally
{
CloseableUtils.closeQuietly(in);
}
return str.toString();
}
}
ExhibitorEnsembleProvider.java 0000664 0000000 0000000 00000026514 12455216776 0040677 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/exhibitor /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.ensemble.exhibitor;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.curator.RetryLoop;
import org.apache.curator.RetryPolicy;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.utils.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
* Ensemble provider that polls a cluster of Exhibitor (https://github.com/Netflix/exhibitor)
* instances for the connection string.
* If the set of instances should change, new ZooKeeper connections will use the new connection
* string.
*/
public class ExhibitorEnsembleProvider implements EnsembleProvider
{
private final Logger log = LoggerFactory.getLogger(getClass());
private final AtomicReference exhibitors = new AtomicReference();
private final AtomicReference masterExhibitors = new AtomicReference();
private final ExhibitorRestClient restClient;
private final String restUriPath;
private final int pollingMs;
private final RetryPolicy retryPolicy;
private final ScheduledExecutorService service = ThreadUtils.newSingleThreadScheduledExecutor("ExhibitorEnsembleProvider");
private final Random random = new Random();
private final AtomicReference connectionString = new AtomicReference("");
private final AtomicReference state = new AtomicReference(State.LATENT);
private static final String MIME_TYPE = "application/x-www-form-urlencoded";
private static final String VALUE_PORT = "port";
private static final String VALUE_COUNT = "count";
private static final String VALUE_SERVER_PREFIX = "server";
private enum State
{
LATENT,
STARTED,
CLOSED
}
/**
* @param exhibitors the current set of exhibitor instances (can be changed later via {@link #setExhibitors(Exhibitors)})
* @param restClient the rest client to use (use {@link DefaultExhibitorRestClient} for most cases)
* @param restUriPath the path of the REST call used to get the server set. Usually: /exhibitor/v1/cluster/list
* @param pollingMs how ofter to poll the exhibitors for the list
* @param retryPolicy retry policy to use when connecting to the exhibitors
*/
public ExhibitorEnsembleProvider(Exhibitors exhibitors, ExhibitorRestClient restClient, String restUriPath, int pollingMs, RetryPolicy retryPolicy)
{
this.exhibitors.set(exhibitors);
this.masterExhibitors.set(exhibitors);
this.restClient = restClient;
this.restUriPath = restUriPath;
this.pollingMs = pollingMs;
this.retryPolicy = retryPolicy;
}
/**
* Change the set of exhibitors to poll
*
* @param newExhibitors new set
*/
public void setExhibitors(Exhibitors newExhibitors)
{
exhibitors.set(newExhibitors);
masterExhibitors.set(newExhibitors);
}
/**
* Can be called prior to starting the Curator instance to set the current connection string
*
* @throws Exception errors
*/
public void pollForInitialEnsemble() throws Exception
{
Preconditions.checkState(state.get() == State.LATENT, "Cannot be called after start()");
poll();
}
@Override
public void start() throws Exception
{
Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once");
service.scheduleWithFixedDelay
(
new Runnable()
{
@Override
public void run()
{
poll();
}
},
pollingMs,
pollingMs,
TimeUnit.MILLISECONDS
);
}
@Override
public void close() throws IOException
{
Preconditions.checkState(state.compareAndSet(State.STARTED, State.CLOSED), "Already closed or has not been started");
service.shutdownNow();
}
@Override
public String getConnectionString()
{
return connectionString.get();
}
@VisibleForTesting
protected void poll()
{
Exhibitors localExhibitors = exhibitors.get();
Map values = queryExhibitors(localExhibitors);
int count = getCountFromValues(values);
if ( count == 0 )
{
log.warn("0 count returned from Exhibitors. Using backup connection values.");
values = useBackup(localExhibitors);
count = getCountFromValues(values);
}
if ( count > 0 )
{
int port = Integer.parseInt(values.get(VALUE_PORT));
StringBuilder newConnectionString = new StringBuilder();
List newHostnames = Lists.newArrayList();
for ( int i = 0; i < count; ++i )
{
if ( newConnectionString.length() > 0 )
{
newConnectionString.append(",");
}
String server = values.get(VALUE_SERVER_PREFIX + i);
newConnectionString.append(server).append(":").append(port);
newHostnames.add(server);
}
String newConnectionStringValue = newConnectionString.toString();
if ( !newConnectionStringValue.equals(connectionString.get()) )
{
log.info(String.format("Connection string has changed. Old value (%s), new value (%s)", connectionString.get(), newConnectionStringValue));
}
Exhibitors newExhibitors = new Exhibitors
(
newHostnames,
localExhibitors.getRestPort(),
new Exhibitors.BackupConnectionStringProvider()
{
@Override
public String getBackupConnectionString() throws Exception
{
return masterExhibitors.get().getBackupConnectionString(); // this may be overloaded by clients. Make sure there is always a method call to get the value.
}
}
);
connectionString.set(newConnectionStringValue);
exhibitors.set(newExhibitors);
}
}
private int getCountFromValues(Map values)
{
try
{
return Integer.parseInt(values.get(VALUE_COUNT));
}
catch ( NumberFormatException e )
{
// ignore
}
return 0;
}
private Map useBackup(Exhibitors localExhibitors)
{
Map values = newValues();
try
{
String backupConnectionString = localExhibitors.getBackupConnectionString();
int thePort = -1;
int count = 0;
for ( String spec : backupConnectionString.split(",") )
{
spec = spec.trim();
String[] parts = spec.split(":");
if ( parts.length == 2 )
{
String hostname = parts[0];
int port = Integer.parseInt(parts[1]);
if ( thePort < 0 )
{
thePort = port;
}
else if ( port != thePort )
{
log.warn("Inconsistent port in connection component: " + spec);
}
values.put(VALUE_SERVER_PREFIX + count, hostname);
++count;
}
else
{
log.warn("Bad backup connection component: " + spec);
}
}
values.put(VALUE_COUNT, Integer.toString(count));
values.put(VALUE_PORT, Integer.toString(thePort));
}
catch ( Exception e )
{
log.error("Couldn't get backup connection string", e);
}
return values;
}
private Map newValues()
{
Map values = Maps.newHashMap();
values.put(VALUE_COUNT, "0");
return values;
}
private static Map decodeExhibitorList(String str) throws UnsupportedEncodingException
{
Map values = Maps.newHashMap();
for ( String spec : str.split("&") )
{
String[] parts = spec.split("=");
if ( parts.length == 2 )
{
values.put(parts[0], URLDecoder.decode(parts[1], "UTF-8"));
}
}
return values;
}
private Map queryExhibitors(Exhibitors localExhibitors)
{
Map values = newValues();
long start = System.currentTimeMillis();
int retries = 0;
boolean done = false;
while ( !done )
{
List hostnames = Lists.newArrayList(localExhibitors.getHostnames());
if ( hostnames.size() == 0 )
{
done = true;
}
else
{
String hostname = hostnames.get(random.nextInt(hostnames.size()));
try
{
String encoded = restClient.getRaw(hostname, localExhibitors.getRestPort(), restUriPath, MIME_TYPE);
values.putAll(decodeExhibitorList(encoded));
done = true;
}
catch ( Throwable e )
{
if ( retryPolicy.allowRetry(retries++, System.currentTimeMillis() - start, RetryLoop.getDefaultRetrySleeper()) )
{
log.warn("Couldn't get servers from Exhibitor. Retrying.", e);
}
else
{
log.error("Couldn't get servers from Exhibitor. Giving up.", e);
done = true;
}
}
}
}
return values;
}
}
ExhibitorRestClient.java 0000664 0000000 0000000 00000002407 12455216776 0037501 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/exhibitor /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.ensemble.exhibitor;
public interface ExhibitorRestClient
{
/**
* Connect to the given Exhibitor and return the raw result
*
* @param hostname host to connect to
* @param port connect port
* @param uriPath path
* @param mimeType Accept mime type
* @return raw result
* @throws Exception errors
*/
public String getRaw(String hostname, int port, String uriPath, String mimeType) throws Exception;
}
Exhibitors.java 0000664 0000000 0000000 00000004525 12455216776 0035672 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/exhibitor /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.ensemble.exhibitor;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
/**
* POJO for specifying the cluster of Exhibitor instances
*/
public class Exhibitors
{
private final Collection hostnames;
private final int restPort;
private final BackupConnectionStringProvider backupConnectionStringProvider;
public interface BackupConnectionStringProvider
{
public String getBackupConnectionString() throws Exception;
}
/**
* @param hostnames set of Exhibitor instance host names
* @param restPort the REST port used to connect to Exhibitor
* @param backupConnectionStringProvider in case an Exhibitor instance can't be contacted, returns the fixed
* connection string to use as a backup
*/
public Exhibitors(Collection hostnames, int restPort, BackupConnectionStringProvider backupConnectionStringProvider)
{
this.backupConnectionStringProvider = Preconditions.checkNotNull(backupConnectionStringProvider, "backupConnectionStringProvider cannot be null");
this.hostnames = ImmutableList.copyOf(hostnames);
this.restPort = restPort;
}
public Collection getHostnames()
{
return hostnames;
}
public int getRestPort()
{
return restPort;
}
public String getBackupConnectionString() throws Exception
{
return backupConnectionStringProvider.getBackupConnectionString();
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/fixed/ 0000775 0000000 0000000 00000000000 12455216776 0032062 5 ustar 00root root 0000000 0000000 FixedEnsembleProvider.java 0000664 0000000 0000000 00000003275 12455216776 0037102 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/ensemble/fixed /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.ensemble.fixed;
import com.google.common.base.Preconditions;
import org.apache.curator.ensemble.EnsembleProvider;
import java.io.IOException;
/**
* Standard ensemble provider that wraps a fixed connection string
*/
public class FixedEnsembleProvider implements EnsembleProvider
{
private final String connectionString;
/**
* The connection string to use
*
* @param connectionString connection string
*/
public FixedEnsembleProvider(String connectionString)
{
this.connectionString = Preconditions.checkNotNull(connectionString, "connectionString cannot be null");
}
@Override
public void start() throws Exception
{
// NOP
}
@Override
public void close() throws IOException
{
// NOP
}
@Override
public String getConnectionString()
{
return connectionString;
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry/ 0000775 0000000 0000000 00000000000 12455216776 0030336 5 ustar 00root root 0000000 0000000 BoundedExponentialBackoffRetry.java 0000664 0000000 0000000 00000003510 12455216776 0037212 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.retry;
import com.google.common.annotations.VisibleForTesting;
/**
* Retry policy that retries a set number of times with an increasing (up to a maximum bound) sleep time between retries
*/
public class BoundedExponentialBackoffRetry extends ExponentialBackoffRetry
{
private final int maxSleepTimeMs;
/**
* @param baseSleepTimeMs initial amount of time to wait between retries
* @param maxSleepTimeMs maximum amount of time to wait between retries
* @param maxRetries maximum number of times to retry
*/
public BoundedExponentialBackoffRetry(int baseSleepTimeMs, int maxSleepTimeMs, int maxRetries)
{
super(baseSleepTimeMs, maxRetries);
this.maxSleepTimeMs = maxSleepTimeMs;
}
@VisibleForTesting
public int getMaxSleepTimeMs()
{
return maxSleepTimeMs;
}
@Override
protected int getSleepTimeMs(int retryCount, long elapsedTimeMs)
{
return Math.min(maxSleepTimeMs, super.getSleepTimeMs(retryCount, elapsedTimeMs));
}
} ExponentialBackoffRetry.java 0000664 0000000 0000000 00000006056 12455216776 0035721 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.retry;
import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Random;
/**
* Retry policy that retries a set number of times with increasing sleep time between retries
*/
public class ExponentialBackoffRetry extends SleepingRetry
{
private static final Logger log = LoggerFactory.getLogger(ExponentialBackoffRetry.class);
private static final int MAX_RETRIES_LIMIT = 29;
private static final int DEFAULT_MAX_SLEEP_MS = Integer.MAX_VALUE;
private final Random random = new Random();
private final int baseSleepTimeMs;
private final int maxSleepMs;
/**
* @param baseSleepTimeMs initial amount of time to wait between retries
* @param maxRetries max number of times to retry
*/
public ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries)
{
this(baseSleepTimeMs, maxRetries, DEFAULT_MAX_SLEEP_MS);
}
/**
* @param baseSleepTimeMs initial amount of time to wait between retries
* @param maxRetries max number of times to retry
* @param maxSleepMs max time in ms to sleep on each retry
*/
public ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)
{
super(validateMaxRetries(maxRetries));
this.baseSleepTimeMs = baseSleepTimeMs;
this.maxSleepMs = maxSleepMs;
}
@VisibleForTesting
public int getBaseSleepTimeMs()
{
return baseSleepTimeMs;
}
@Override
protected int getSleepTimeMs(int retryCount, long elapsedTimeMs)
{
// copied from Hadoop's RetryPolicies.java
int sleepMs = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)));
if ( sleepMs > maxSleepMs )
{
log.warn(String.format("Sleep extension too large (%d). Pinning to %d", sleepMs, maxSleepMs));
sleepMs = maxSleepMs;
}
return sleepMs;
}
private static int validateMaxRetries(int maxRetries)
{
if ( maxRetries > MAX_RETRIES_LIMIT )
{
log.warn(String.format("maxRetries too large (%d). Pinning to %d", maxRetries, MAX_RETRIES_LIMIT));
maxRetries = MAX_RETRIES_LIMIT;
}
return maxRetries;
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry/RetryNTimes.java 0000664 0000000 0000000 00000002401 12455216776 0033423 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.retry;
/**
* Retry policy that retries a max number of times
*/
public class RetryNTimes extends SleepingRetry
{
private final int sleepMsBetweenRetries;
public RetryNTimes(int n, int sleepMsBetweenRetries)
{
super(n);
this.sleepMsBetweenRetries = sleepMsBetweenRetries;
}
@Override
protected int getSleepTimeMs(int retryCount, long elapsedTimeMs)
{
return sleepMsBetweenRetries;
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry/RetryOneTime.java0000664 0000000 0000000 00000002023 12455216776 0033564 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.retry;
/**
* A retry policy that retries only once
*/
public class RetryOneTime extends RetryNTimes
{
public RetryOneTime(int sleepMsBetweenRetry)
{
super(1, sleepMsBetweenRetry);
}
}
RetryUntilElapsed.java 0000664 0000000 0000000 00000003237 12455216776 0034546 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.retry;
import org.apache.curator.RetrySleeper;
/**
* A retry policy that retries until a given amount of time elapses
*/
public class RetryUntilElapsed extends SleepingRetry
{
private final int maxElapsedTimeMs;
private final int sleepMsBetweenRetries;
public RetryUntilElapsed(int maxElapsedTimeMs, int sleepMsBetweenRetries)
{
super(Integer.MAX_VALUE);
this.maxElapsedTimeMs = maxElapsedTimeMs;
this.sleepMsBetweenRetries = sleepMsBetweenRetries;
}
@Override
public boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper)
{
return super.allowRetry(retryCount, elapsedTimeMs, sleeper) && (elapsedTimeMs < maxElapsedTimeMs);
}
@Override
protected int getSleepTimeMs(int retryCount, long elapsedTimeMs)
{
return sleepMsBetweenRetries;
}
}
SleepingRetry.java 0000664 0000000 0000000 00000003356 12455216776 0033725 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/retry /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.retry;
import org.apache.curator.RetryPolicy;
import org.apache.curator.RetrySleeper;
import java.util.concurrent.TimeUnit;
abstract class SleepingRetry implements RetryPolicy
{
private final int n;
protected SleepingRetry(int n)
{
this.n = n;
}
// made public for testing
public int getN()
{
return n;
}
public boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper)
{
if ( retryCount < n )
{
try
{
sleeper.sleepFor(getSleepTimeMs(retryCount, elapsedTimeMs), TimeUnit.MILLISECONDS);
}
catch ( InterruptedException e )
{
Thread.currentThread().interrupt();
return false;
}
return true;
}
return false;
}
protected abstract int getSleepTimeMs(int retryCount, long elapsedTimeMs);
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils/ 0000775 0000000 0000000 00000000000 12455216776 0030331 5 ustar 00root root 0000000 0000000 CloseableExecutorService.java 0000664 0000000 0000000 00000013533 12455216776 0036053 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Decoration on an ExecutorService that tracks created futures and provides
* a method to close futures created via this class
*/
public class CloseableExecutorService implements Closeable
{
private final Logger log = LoggerFactory.getLogger(CloseableExecutorService.class);
private final Set> futures = Sets.newSetFromMap(Maps., Boolean>newConcurrentMap());
private final ExecutorService executorService;
private final boolean shutdownOnClose;
protected final AtomicBoolean isOpen = new AtomicBoolean(true);
protected class InternalScheduledFutureTask implements Future
{
private final ScheduledFuture> scheduledFuture;
public InternalScheduledFutureTask(ScheduledFuture> scheduledFuture)
{
this.scheduledFuture = scheduledFuture;
futures.add(scheduledFuture);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning)
{
futures.remove(scheduledFuture);
return scheduledFuture.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled()
{
return scheduledFuture.isCancelled();
}
@Override
public boolean isDone()
{
return scheduledFuture.isDone();
}
@Override
public Void get() throws InterruptedException, ExecutionException
{
return null;
}
@Override
public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return null;
}
}
protected class InternalFutureTask extends FutureTask
{
private final RunnableFuture task;
InternalFutureTask(RunnableFuture task)
{
super(task, null);
this.task = task;
futures.add(task);
}
protected void done()
{
futures.remove(task);
}
}
/**
* @param executorService the service to decorate
*/
public CloseableExecutorService(ExecutorService executorService)
{
this(executorService, false);
}
/**
* @param executorService the service to decorate
* @param shutdownOnClose if true, shutdown the executor service when this is closed
*/
public CloseableExecutorService(ExecutorService executorService, boolean shutdownOnClose)
{
this.executorService = Preconditions.checkNotNull(executorService, "executorService cannot be null");
this.shutdownOnClose = shutdownOnClose;
}
/**
* Returns true if this executor has been shut down.
*
* @return true if this executor has been shut down
*/
public boolean isShutdown()
{
return !isOpen.get();
}
@VisibleForTesting
int size()
{
return futures.size();
}
/**
* Closes any tasks currently in progress
*/
@Override
public void close()
{
isOpen.set(false);
Iterator> iterator = futures.iterator();
while ( iterator.hasNext() )
{
Future> future = iterator.next();
iterator.remove();
if ( !future.isDone() && !future.isCancelled() && !future.cancel(true) )
{
log.warn("Could not cancel " + future);
}
}
if (shutdownOnClose) {
executorService.shutdownNow();
}
}
/**
* Submits a value-returning task for execution and returns a Future
* representing the pending results of the task. Upon completion,
* this task may be taken or polled.
*
* @param task the task to submit
* @return a future to watch the task
*/
public Future submit(Callable task)
{
Preconditions.checkState(isOpen.get(), "CloseableExecutorService is closed");
InternalFutureTask futureTask = new InternalFutureTask(new FutureTask(task));
executorService.execute(futureTask);
return futureTask;
}
/**
* Submits a Runnable task for execution and returns a Future
* representing that task. Upon completion, this task may be
* taken or polled.
*
* @param task the task to submit
* @return a future to watch the task
*/
public Future> submit(Runnable task)
{
Preconditions.checkState(isOpen.get(), "CloseableExecutorService is closed");
InternalFutureTask futureTask = new InternalFutureTask(new FutureTask(task, null));
executorService.execute(futureTask);
return futureTask;
}
}
CloseableScheduledExecutorService.java 0000664 0000000 0000000 00000010331 12455216776 0037665 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
import com.google.common.base.Preconditions;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* Decoration on an ScheduledExecutorService that tracks created futures and provides
* a method to close futures created via this class
*/
public class CloseableScheduledExecutorService extends CloseableExecutorService
{
private final ScheduledExecutorService scheduledExecutorService;
/**
* @param scheduledExecutorService the service to decorate
*/
public CloseableScheduledExecutorService(ScheduledExecutorService scheduledExecutorService)
{
super(scheduledExecutorService, false);
this.scheduledExecutorService = scheduledExecutorService;
}
/**
* @param scheduledExecutorService the service to decorate
* @param shutdownOnClose if true, shutdown the executor service when this is closed
*/
public CloseableScheduledExecutorService(ScheduledExecutorService scheduledExecutorService, boolean shutdownOnClose)
{
super(scheduledExecutorService, shutdownOnClose);
this.scheduledExecutorService = scheduledExecutorService;
}
/**
* Creates and executes a one-shot action that becomes enabled
* after the given delay.
*
* @param task the task to execute
* @param delay the time from now to delay execution
* @param unit the time unit of the delay parameter
* @return a Future representing pending completion of
* the task and whose get() method will return
* null upon completion
*/
public Future> schedule(Runnable task, long delay, TimeUnit unit)
{
Preconditions.checkState(isOpen.get(), "CloseableExecutorService is closed");
InternalFutureTask futureTask = new InternalFutureTask(new FutureTask(task, null));
scheduledExecutorService.schedule(futureTask, delay, unit);
return futureTask;
}
/**
* Creates and executes a periodic action that becomes enabled first
* after the given initial delay, and subsequently with the
* given delay between the termination of one execution and the
* commencement of the next. If any execution of the task
* encounters an exception, subsequent executions are suppressed.
* Otherwise, the task will only terminate via cancellation or
* termination of the executor.
*
* @param task the task to execute
* @param initialDelay the time to delay first execution
* @param delay the delay between the termination of one
* execution and the commencement of the next
* @param unit the time unit of the initialDelay and delay parameters
* @return a Future representing pending completion of
* the task, and whose get() method will throw an
* exception upon cancellation
*/
public Future> scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit)
{
Preconditions.checkState(isOpen.get(), "CloseableExecutorService is closed");
ScheduledFuture> scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(task, initialDelay, delay, unit);
return new InternalScheduledFutureTask(scheduledFuture);
}
}
CloseableUtils.java 0000664 0000000 0000000 00000005000 12455216776 0034022 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
import com.google.common.io.Closeables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
/**
* This class adds back functionality that was removed in Guava v16.0.
*/
public class CloseableUtils
{
private static final Logger log = LoggerFactory.getLogger(CloseableUtils.class);
/**
*
* This method has been added because Guava has removed the
* {@code closeQuietly()} method from {@code Closeables} in v16.0. It's
* tempting simply to replace calls to {@code closeQuietly(closeable)}
* with calls to {@code close(closeable, true)} to close
* {@code Closeable}s while swallowing {@code IOException}s, but
* {@code close()} is declared as {@code throws IOException} whereas
* {@code closeQuietly()} is not, so it's not a drop-in replacement.
*
*
* On the whole, Guava is very backwards compatible. By fixing this nit,
* Curator can continue to support newer versions of Guava without having
* to bump its own dependency version.
*
*/
public static void closeQuietly(Closeable closeable)
{
try
{
// Here we've instructed Guava to swallow the IOException
Closeables.close(closeable, true);
}
catch ( IOException e )
{
// We instructed Guava to swallow the IOException, so this should
// never happen. Since it did, log it.
log.error("IOException should not have been thrown.", e);
}
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils/DebugUtils.java 0000664 0000000 0000000 00000002364 12455216776 0033250 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
public class DebugUtils
{
public static final String PROPERTY_LOG_EVENTS = "curator-log-events";
public static final String PROPERTY_DONT_LOG_CONNECTION_ISSUES = "curator-dont-log-connection-problems";
public static final String PROPERTY_LOG_ONLY_FIRST_CONNECTION_ISSUE_AS_ERROR_LEVEL = "curator-log-only-first-connection-issue-as-error-level";
private DebugUtils()
{
}
}
DefaultTracerDriver.java 0000664 0000000 0000000 00000003073 12455216776 0035021 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
import org.apache.curator.drivers.TracerDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* Default tracer driver
*/
public class DefaultTracerDriver implements TracerDriver
{
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
public void addTrace(String name, long time, TimeUnit unit)
{
if ( log.isTraceEnabled() )
{
log.trace("Trace: " + name + " - " + TimeUnit.MILLISECONDS.convert(time, unit) + " ms");
}
}
@Override
public void addCount(String name, int increment)
{
if ( log.isTraceEnabled() )
{
log.trace("Counter " + name + ": " + increment);
}
}
}
DefaultZookeeperFactory.java 0000664 0000000 0000000 00000002322 12455216776 0035714 0 ustar 00root root 0000000 0000000 curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
public class DefaultZookeeperFactory implements ZookeeperFactory
{
@Override
public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly) throws Exception
{
return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly);
}
}
curator-apache-curator-2.7.1/curator-client/src/main/java/org/apache/curator/utils/EnsurePath.java 0000664 0000000 0000000 00000011762 12455216776 0033261 0 ustar 00root root 0000000 0000000 /**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.curator.utils;
import org.apache.curator.CuratorZookeeperClient;
import org.apache.curator.RetryLoop;
import org.apache.zookeeper.ZooKeeper;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
/**
*
* Utility to ensure that a particular path is created.
*
*
* The first time it is used, a synchronized call to {@link ZKPaths#mkdirs(ZooKeeper, String)} is made to
* ensure that the entire path has been created (with an empty byte array if needed). Subsequent
* calls with the instance are un-synchronized NOPs.
*
*
* Usage:
*
*
* EnsurePath ensurePath = new EnsurePath(aFullPathToEnsure);
* ...
* String nodePath = aFullPathToEnsure + "/foo";
* ensurePath.ensure(zk); // first time syncs and creates if needed
* zk.create(nodePath, ...);
* ...
* ensurePath.ensure(zk); // subsequent times are NOPs
* zk.create(nodePath, ...);
*
*/
public class EnsurePath
{
private final String path;
private final boolean makeLastNode;
private final InternalACLProvider aclProvider;
private final AtomicReference helper;
private static final Helper doNothingHelper = new Helper()
{
@Override
public void ensure(CuratorZookeeperClient client, String path, final boolean makeLastNode) throws Exception
{
// NOP
}
};
private interface Helper
{
public void ensure(CuratorZookeeperClient client, String path, final boolean makeLastNode) throws Exception;
}
/**
* @param path the full path to ensure
*/
public EnsurePath(String path)
{
this(path, null, true, null);
}
/**
* @param path the full path to ensure
* @param aclProvider if not null, the ACL provider to use when creating parent nodes
*/
public EnsurePath(String path, InternalACLProvider aclProvider)
{
this(path, null, true, aclProvider);
}
/**
* First time, synchronizes and makes sure all nodes in the path are created. Subsequent calls
* with this instance are NOPs.
*
* @param client ZK client
* @throws Exception ZK errors
*/
public void ensure(CuratorZookeeperClient client) throws Exception
{
Helper localHelper = helper.get();
localHelper.ensure(client, path, makeLastNode);
}
/**
* Returns a view of this EnsurePath instance that does not make the last node.
* i.e. if the path is "/a/b/c" only "/a/b" will be ensured
*
* @return view
*/
public EnsurePath excludingLast()
{
return new EnsurePath(path, helper, false, aclProvider);
}
private EnsurePath(String path, AtomicReference helper, boolean makeLastNode, InternalACLProvider aclProvider)
{
this.path = path;
this.makeLastNode = makeLastNode;
this.aclProvider = aclProvider;
this.helper = (helper != null) ? helper : new AtomicReference(new InitialHelper());
}
/**
* Returns the path being Ensured
*
* @return the path being ensured
*/
public String getPath()
{
return this.path;
}
private class InitialHelper implements Helper
{
private boolean isSet = false; // guarded by synchronization
@Override
public synchronized void ensure(final CuratorZookeeperClient client, final String path, final boolean makeLastNode) throws Exception
{
if ( !isSet )
{
RetryLoop.callWithRetry
(
client,
new Callable