http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java deleted file mode 100644 index 720619d..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientCnxnSocketNIO.java +++ /dev/null @@ -1,431 +0,0 @@ -/** - * 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.zookeeper; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.SocketChannel; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Set; - -import org.apache.zookeeper.ClientCnxn.EndOfStreamException; -import org.apache.zookeeper.ClientCnxn.Packet; -import org.apache.zookeeper.ZooDefs.OpCode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ClientCnxnSocketNIO extends ClientCnxnSocket { - private static final Logger LOG = LoggerFactory - .getLogger(ClientCnxnSocketNIO.class); - - private final Selector selector = Selector.open(); - - private SelectionKey sockKey; - - ClientCnxnSocketNIO() throws IOException { - super(); - } - - @Override - boolean isConnected() { - return sockKey != null; - } - - /** - * @return true if a packet was received - * @throws InterruptedException - * @throws IOException - */ - void doIO(List<Packet> pendingQueue, LinkedList<Packet> outgoingQueue, ClientCnxn cnxn) - throws InterruptedException, IOException { - SocketChannel sock = (SocketChannel) sockKey.channel(); - if (sock == null) { - throw new IOException("Socket is null!"); - } - if (sockKey.isReadable()) { - int rc = sock.read(incomingBuffer); - if (rc < 0) { - throw new EndOfStreamException( - "Unable to read additional data from server sessionid 0x" - + Long.toHexString(sessionId) - + ", likely server has closed socket"); - } - if (!incomingBuffer.hasRemaining()) { - incomingBuffer.flip(); - if (incomingBuffer == lenBuffer) { - recvCount++; - readLength(); - } else if (!initialized) { - readConnectResult(); - enableRead(); - if (findSendablePacket(outgoingQueue, - cnxn.sendThread.clientTunneledAuthenticationInProgress()) != null) { - // Since SASL authentication has completed (if client is configured to do so), - // outgoing packets waiting in the outgoingQueue can now be sent. - enableWrite(); - } - lenBuffer.clear(); - incomingBuffer = lenBuffer; - updateLastHeard(); - initialized = true; - } else { - sendThread.readResponse(incomingBuffer); - lenBuffer.clear(); - incomingBuffer = lenBuffer; - updateLastHeard(); - } - } - } - if (sockKey.isWritable()) { - synchronized(outgoingQueue) { - Packet p = findSendablePacket(outgoingQueue, - cnxn.sendThread.clientTunneledAuthenticationInProgress()); - - if (p != null) { - updateLastSend(); - // If we already started writing p, p.bb will already exist - if (p.bb == null) { - if ((p.requestHeader != null) && - (p.requestHeader.getType() != OpCode.ping) && - (p.requestHeader.getType() != OpCode.auth)) { - p.requestHeader.setXid(cnxn.getXid()); - } - p.createBB(); - } - sock.write(p.bb); - if (!p.bb.hasRemaining()) { - sentCount++; - outgoingQueue.removeFirstOccurrence(p); - if (p.requestHeader != null - && p.requestHeader.getType() != OpCode.ping - && p.requestHeader.getType() != OpCode.auth) { - synchronized (pendingQueue) { - pendingQueue.add(p); - } - } - } - } - if (outgoingQueue.isEmpty()) { - // No more packets to send: turn off write interest flag. - // Will be turned on later by a later call to enableWrite(), - // from within ZooKeeperSaslClient (if client is configured - // to attempt SASL authentication), or in either doIO() or - // in doTransport() if not. - disableWrite(); - } else if (!initialized && p != null && !p.bb.hasRemaining()) { - // On initial connection, write the complete connect request - // packet, but then disable further writes until after - // receiving a successful connection response. If the - // session is expired, then the server sends the expiration - // response and immediately closes its end of the socket. If - // the client is simultaneously writing on its end, then the - // TCP stack may choose to abort with RST, in which case the - // client would never receive the session expired event. See - // http://docs.oracle.com/javase/6/docs/technotes/guides/net/articles/connection_release.html - disableWrite(); - } else { - // Just in case - enableWrite(); - } - } - } - } - - private Packet findSendablePacket(LinkedList<Packet> outgoingQueue, - boolean clientTunneledAuthenticationInProgress) { - synchronized (outgoingQueue) { - if (outgoingQueue.isEmpty()) { - return null; - } - if (outgoingQueue.getFirst().bb != null // If we've already starting sending the first packet, we better finish - || !clientTunneledAuthenticationInProgress) { - return outgoingQueue.getFirst(); - } - - // Since client's authentication with server is in progress, - // send only the null-header packet queued by primeConnection(). - // This packet must be sent so that the SASL authentication process - // can proceed, but all other packets should wait until - // SASL authentication completes. - ListIterator<Packet> iter = outgoingQueue.listIterator(); - while (iter.hasNext()) { - Packet p = iter.next(); - if (p.requestHeader == null) { - // We've found the priming-packet. Move it to the beginning of the queue. - iter.remove(); - outgoingQueue.add(0, p); - return p; - } else { - // Non-priming packet: defer it until later, leaving it in the queue - // until authentication completes. - if (LOG.isDebugEnabled()) { - LOG.debug("deferring non-priming packet: " + p + - "until SASL authentication completes."); - } - } - } - // no sendable packet found. - return null; - } - } - - @Override - void cleanup() { - if (sockKey != null) { - SocketChannel sock = (SocketChannel) sockKey.channel(); - sockKey.cancel(); - try { - sock.socket().shutdownInput(); - } catch (IOException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Ignoring exception during shutdown input", e); - } - } - try { - sock.socket().shutdownOutput(); - } catch (IOException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Ignoring exception during shutdown output", - e); - } - } - try { - sock.socket().close(); - } catch (IOException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Ignoring exception during socket close", e); - } - } - try { - sock.close(); - } catch (IOException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Ignoring exception during channel close", e); - } - } - } - try { - Thread.sleep(100); - } catch (InterruptedException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("SendThread interrupted during sleep, ignoring"); - } - } - sockKey = null; - } - - @Override - void close() { - try { - if (LOG.isTraceEnabled()) { - LOG.trace("Doing client selector close"); - } - selector.close(); - if (LOG.isTraceEnabled()) { - LOG.trace("Closed client selector"); - } - } catch (IOException e) { - LOG.warn("Ignoring exception during selector close", e); - } - } - - /** - * create a socket channel. - * @return the created socket channel - * @throws IOException - */ - SocketChannel createSock() throws IOException { - SocketChannel sock; - sock = SocketChannel.open(); - sock.configureBlocking(false); - sock.socket().setSoLinger(false, -1); - sock.socket().setTcpNoDelay(true); - return sock; - } - - /** - * register with the selection and connect - * @param sock the {@link SocketChannel} - * @param addr the address of remote host - * @throws IOException - */ - void registerAndConnect(SocketChannel sock, InetSocketAddress addr) - throws IOException { - sockKey = sock.register(selector, SelectionKey.OP_CONNECT); - boolean immediateConnect = sock.connect(addr); - if (immediateConnect) { - sendThread.primeConnection(); - } - } - - @Override - void connect(InetSocketAddress addr) throws IOException { - SocketChannel sock = createSock(); - try { - registerAndConnect(sock, addr); - } catch (IOException e) { - LOG.error("Unable to open socket to " + addr); - sock.close(); - throw e; - } - initialized = false; - - /* - * Reset incomingBuffer - */ - lenBuffer.clear(); - incomingBuffer = lenBuffer; - } - - /** - * Returns the address to which the socket is connected. - * - * @return ip address of the remote side of the connection or null if not - * connected - */ - @Override - SocketAddress getRemoteSocketAddress() { - // a lot could go wrong here, so rather than put in a bunch of code - // to check for nulls all down the chain let's do it the simple - // yet bulletproof way - try { - return ((SocketChannel) sockKey.channel()).socket() - .getRemoteSocketAddress(); - } catch (NullPointerException e) { - return null; - } - } - - /** - * Returns the local address to which the socket is bound. - * - * @return ip address of the remote side of the connection or null if not - * connected - */ - @Override - SocketAddress getLocalSocketAddress() { - // a lot could go wrong here, so rather than put in a bunch of code - // to check for nulls all down the chain let's do it the simple - // yet bulletproof way - try { - return ((SocketChannel) sockKey.channel()).socket() - .getLocalSocketAddress(); - } catch (NullPointerException e) { - return null; - } - } - - @Override - synchronized void wakeupCnxn() { - selector.wakeup(); - } - - @Override - void doTransport(int waitTimeOut, List<Packet> pendingQueue, LinkedList<Packet> outgoingQueue, - ClientCnxn cnxn) - throws IOException, InterruptedException { - selector.select(waitTimeOut); - Set<SelectionKey> selected; - synchronized (this) { - selected = selector.selectedKeys(); - } - // Everything below and until we get back to the select is - // non blocking, so time is effectively a constant. That is - // Why we just have to do this once, here - updateNow(); - for (SelectionKey k : selected) { - SocketChannel sc = ((SocketChannel) k.channel()); - if ((k.readyOps() & SelectionKey.OP_CONNECT) != 0) { - if (sc.finishConnect()) { - updateLastSendAndHeard(); - sendThread.primeConnection(); - } - } else if ((k.readyOps() & (SelectionKey.OP_READ | SelectionKey.OP_WRITE)) != 0) { - doIO(pendingQueue, outgoingQueue, cnxn); - } - } - if (sendThread.getZkState().isConnected()) { - synchronized(outgoingQueue) { - if (findSendablePacket(outgoingQueue, - cnxn.sendThread.clientTunneledAuthenticationInProgress()) != null) { - enableWrite(); - } - } - } - selected.clear(); - } - - //TODO should this be synchronized? - @Override - void testableCloseSocket() throws IOException { - LOG.info("testableCloseSocket() called"); - ((SocketChannel) sockKey.channel()).socket().close(); - } - - @Override - synchronized void enableWrite() { - int i = sockKey.interestOps(); - if ((i & SelectionKey.OP_WRITE) == 0) { - sockKey.interestOps(i | SelectionKey.OP_WRITE); - } - } - - @Override - public synchronized void disableWrite() { - int i = sockKey.interestOps(); - if ((i & SelectionKey.OP_WRITE) != 0) { - sockKey.interestOps(i & (~SelectionKey.OP_WRITE)); - } - } - - synchronized private void enableRead() { - int i = sockKey.interestOps(); - if ((i & SelectionKey.OP_READ) == 0) { - sockKey.interestOps(i | SelectionKey.OP_READ); - } - } - - @Override - synchronized void enableReadWriteOnly() { - sockKey.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); - } - - Selector getSelector() { - return selector; - } - - @Override - void sendPacket(Packet p) throws IOException { - SocketChannel sock = (SocketChannel) sockKey.channel(); - if (sock == null) { - throw new IOException("Socket is null!"); - } - p.createBB(); - ByteBuffer pbb = p.bb; - sock.write(pbb); - } - - -}
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java b/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java deleted file mode 100644 index d56374d..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/ClientWatchManager.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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.zookeeper; - -import java.util.Set; - -/** - */ -public interface ClientWatchManager { - /** - * Return a set of watchers that should be notified of the event. The - * manager must not notify the watcher(s), however it will update it's - * internal structure as if the watches had triggered. The intent being - * that the callee is now responsible for notifying the watchers of the - * event, possibly at some later time. - * - * @param state event state - * @param type event type - * @param path event path - * @return may be empty set but must not be null - */ - public Set<Watcher> materialize(Watcher.Event.KeeperState state, - Watcher.Event.EventType type, String path); -} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java b/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java deleted file mode 100644 index 84f5be0..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/CreateMode.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 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.zookeeper; - -import org.apache.yetus.audience.InterfaceAudience; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.zookeeper.KeeperException; - -/*** - * CreateMode value determines how the znode is created on ZooKeeper. - */ -@InterfaceAudience.Public -public enum CreateMode { - - /** - * The znode will not be automatically deleted upon client's disconnect. - */ - PERSISTENT (0, false, false), - /** - * The znode will not be automatically deleted upon client's disconnect, - * and its name will be appended with a monotonically increasing number. - */ - PERSISTENT_SEQUENTIAL (2, false, true), - /** - * The znode will be deleted upon the client's disconnect. - */ - EPHEMERAL (1, true, false), - /** - * The znode will be deleted upon the client's disconnect, and its name - * will be appended with a monotonically increasing number. - */ - EPHEMERAL_SEQUENTIAL (3, true, true); - - private static final Logger LOG = LoggerFactory.getLogger(CreateMode.class); - - private boolean ephemeral; - private boolean sequential; - private int flag; - - CreateMode(int flag, boolean ephemeral, boolean sequential) { - this.flag = flag; - this.ephemeral = ephemeral; - this.sequential = sequential; - } - - public boolean isEphemeral() { - return ephemeral; - } - - public boolean isSequential() { - return sequential; - } - - public int toFlag() { - return flag; - } - - /** - * Map an integer value to a CreateMode value - */ - static public CreateMode fromFlag(int flag) throws KeeperException { - switch(flag) { - case 0: return CreateMode.PERSISTENT; - - case 1: return CreateMode.EPHEMERAL; - - case 2: return CreateMode.PERSISTENT_SEQUENTIAL; - - case 3: return CreateMode.EPHEMERAL_SEQUENTIAL ; - - default: - String errMsg = "Received an invalid flag value: " + flag - + " to convert to a CreateMode"; - LOG.error(errMsg); - throw new KeeperException.BadArgumentsException(errMsg); - } - } -} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java deleted file mode 100644 index 51797a1..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/Environment.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * 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.zookeeper; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Provide insight into the runtime environment. - * - */ -public class Environment { - public static final String JAAS_CONF_KEY = "java.security.auth.login.config"; - - public static class Entry { - private String k; - private String v; - public Entry(String k, String v) { - this.k = k; - this.v = v; - } - public String getKey() { return k; } - public String getValue() { return v; } - - @Override - public String toString() { - return k + "=" + v; - } - } - - private static void put(ArrayList<Entry> l, String k, String v) { - l.add(new Entry(k,v)); - } - - public static List<Entry> list() { - ArrayList<Entry> l = new ArrayList<Entry>(); - put(l, "zookeeper.version", Version.getFullVersion()); - - try { - put(l, "host.name", - InetAddress.getLocalHost().getCanonicalHostName()); - } catch (UnknownHostException e) { - put(l, "host.name", "<NA>"); - } - - put(l, "java.version", - System.getProperty("java.version", "<NA>")); - put(l, "java.vendor", - System.getProperty("java.vendor", "<NA>")); - put(l, "java.home", - System.getProperty("java.home", "<NA>")); - put(l, "java.class.path", - System.getProperty("java.class.path", "<NA>")); - put(l, "java.library.path", - System.getProperty("java.library.path", "<NA>")); - put(l, "java.io.tmpdir", - System.getProperty("java.io.tmpdir", "<NA>")); - put(l, "java.compiler", - System.getProperty("java.compiler", "<NA>")); - put(l, "os.name", - System.getProperty("os.name", "<NA>")); - put(l, "os.arch", - System.getProperty("os.arch", "<NA>")); - put(l, "os.version", - System.getProperty("os.version", "<NA>")); - put(l, "user.name", - System.getProperty("user.name", "<NA>")); - put(l, "user.home", - System.getProperty("user.home", "<NA>")); - put(l, "user.dir", - System.getProperty("user.dir", "<NA>")); - - return l; - } - - public static void logEnv(String msg, Logger log) { - List<Entry> env = Environment.list(); - for (Entry e : env) { - log.info(msg + e.toString()); - } - } -} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java b/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java deleted file mode 100644 index bdf4203..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/KeeperException.java +++ /dev/null @@ -1,728 +0,0 @@ -/** - * 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.zookeeper; - -import org.apache.yetus.audience.InterfaceAudience; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@SuppressWarnings("serial") -@InterfaceAudience.Public -public abstract class KeeperException extends Exception { - /** - * All multi-requests that result in an exception retain the results - * here so that it is possible to examine the problems in the catch - * scope. Non-multi requests will get a null if they try to access - * these results. - */ - private List<OpResult> results; - - /** - * All non-specific keeper exceptions should be constructed via - * this factory method in order to guarantee consistency in error - * codes and such. If you know the error code, then you should - * construct the special purpose exception directly. That will - * allow you to have the most specific possible declarations of - * what exceptions might actually be thrown. - * - * @param code The error code. - * @param path The ZooKeeper path being operated on. - * @return The specialized exception, presumably to be thrown by - * the caller. - */ - public static KeeperException create(Code code, String path) { - KeeperException r = create(code); - r.path = path; - return r; - } - - /** - * @deprecated deprecated in 3.1.0, use {@link #create(Code, String)} - * instead - */ - @Deprecated - public static KeeperException create(int code, String path) { - KeeperException r = create(Code.get(code)); - r.path = path; - return r; - } - - /** - * @deprecated deprecated in 3.1.0, use {@link #create(Code)} - * instead - */ - @Deprecated - public static KeeperException create(int code) { - return create(Code.get(code)); - } - - /** - * All non-specific keeper exceptions should be constructed via - * this factory method in order to guarantee consistency in error - * codes and such. If you know the error code, then you should - * construct the special purpose exception directly. That will - * allow you to have the most specific possible declarations of - * what exceptions might actually be thrown. - * - * @param code The error code of your new exception. This will - * also determine the specific type of the exception that is - * returned. - * @return The specialized exception, presumably to be thrown by - * the caller. - */ - public static KeeperException create(Code code) { - switch (code) { - case SYSTEMERROR: - return new SystemErrorException(); - case RUNTIMEINCONSISTENCY: - return new RuntimeInconsistencyException(); - case DATAINCONSISTENCY: - return new DataInconsistencyException(); - case CONNECTIONLOSS: - return new ConnectionLossException(); - case MARSHALLINGERROR: - return new MarshallingErrorException(); - case UNIMPLEMENTED: - return new UnimplementedException(); - case OPERATIONTIMEOUT: - return new OperationTimeoutException(); - case BADARGUMENTS: - return new BadArgumentsException(); - case APIERROR: - return new APIErrorException(); - case NONODE: - return new NoNodeException(); - case NOAUTH: - return new NoAuthException(); - case BADVERSION: - return new BadVersionException(); - case NOCHILDRENFOREPHEMERALS: - return new NoChildrenForEphemeralsException(); - case NODEEXISTS: - return new NodeExistsException(); - case INVALIDACL: - return new InvalidACLException(); - case AUTHFAILED: - return new AuthFailedException(); - case NOTEMPTY: - return new NotEmptyException(); - case SESSIONEXPIRED: - return new SessionExpiredException(); - case INVALIDCALLBACK: - return new InvalidCallbackException(); - case SESSIONMOVED: - return new SessionMovedException(); - case NOTREADONLY: - return new NotReadOnlyException(); - - case OK: - default: - throw new IllegalArgumentException("Invalid exception code"); - } - } - - /** - * Set the code for this exception - * @param code error code - * @deprecated deprecated in 3.1.0, exceptions should be immutable, this - * method should not be used - */ - @Deprecated - public void setCode(int code) { - this.code = Code.get(code); - } - - /** This interface contains the original static final int constants - * which have now been replaced with an enumeration in Code. Do not - * reference this class directly, if necessary (legacy code) continue - * to access the constants through Code. - * Note: an interface is used here due to the fact that enums cannot - * reference constants defined within the same enum as said constants - * are considered initialized _after_ the enum itself. By using an - * interface as a super type this allows the deprecated constants to - * be initialized first and referenced when constructing the enums. I - * didn't want to have constants declared twice. This - * interface should be private, but it's declared public to enable - * javadoc to include in the user API spec. - */ - @Deprecated - @InterfaceAudience.Public - public interface CodeDeprecated { - /** - * @deprecated deprecated in 3.1.0, use {@link Code#OK} instead - */ - @Deprecated - public static final int Ok = 0; - - /** - * @deprecated deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead - */ - @Deprecated - public static final int SystemError = -1; - /** - * @deprecated deprecated in 3.1.0, use - * {@link Code#RUNTIMEINCONSISTENCY} instead - */ - @Deprecated - public static final int RuntimeInconsistency = -2; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY} - * instead - */ - @Deprecated - public static final int DataInconsistency = -3; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS} - * instead - */ - @Deprecated - public static final int ConnectionLoss = -4; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR} - * instead - */ - @Deprecated - public static final int MarshallingError = -5; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED} - * instead - */ - @Deprecated - public static final int Unimplemented = -6; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT} - * instead - */ - @Deprecated - public static final int OperationTimeout = -7; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#BADARGUMENTS} - * instead - */ - @Deprecated - public static final int BadArguments = -8; - - /** - * @deprecated deprecated in 3.1.0, use {@link Code#APIERROR} instead - */ - @Deprecated - public static final int APIError = -100; - - /** - * @deprecated deprecated in 3.1.0, use {@link Code#NONODE} instead - */ - @Deprecated - public static final int NoNode = -101; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#NOAUTH} instead - */ - @Deprecated - public static final int NoAuth = -102; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#BADVERSION} instead - */ - @Deprecated - public static final int BadVersion = -103; - /** - * @deprecated deprecated in 3.1.0, use - * {@link Code#NOCHILDRENFOREPHEMERALS} - * instead - */ - @Deprecated - public static final int NoChildrenForEphemerals = -108; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead - */ - @Deprecated - public static final int NodeExists = -110; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead - */ - @Deprecated - public static final int NotEmpty = -111; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead - */ - @Deprecated - public static final int SessionExpired = -112; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK} - * instead - */ - @Deprecated - public static final int InvalidCallback = -113; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDACL} instead - */ - @Deprecated - public static final int InvalidACL = -114; - /** - * @deprecated deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead - */ - @Deprecated - public static final int AuthFailed = -115; - /** - * This value will be used directly in {@link CODE#SESSIONMOVED} - */ - // public static final int SessionMoved = -118; - } - - /** Codes which represent the various KeeperException - * types. This enum replaces the deprecated earlier static final int - * constants. The old, deprecated, values are in "camel case" while the new - * enum values are in all CAPS. - */ - @InterfaceAudience.Public - public static enum Code implements CodeDeprecated { - /** Everything is OK */ - OK (Ok), - - /** System and server-side errors. - * This is never thrown by the server, it shouldn't be used other than - * to indicate a range. Specifically error codes greater than this - * value, but lesser than {@link #APIERROR}, are system errors. - */ - SYSTEMERROR (SystemError), - - /** A runtime inconsistency was found */ - RUNTIMEINCONSISTENCY (RuntimeInconsistency), - /** A data inconsistency was found */ - DATAINCONSISTENCY (DataInconsistency), - /** Connection to the server has been lost */ - CONNECTIONLOSS (ConnectionLoss), - /** Error while marshalling or unmarshalling data */ - MARSHALLINGERROR (MarshallingError), - /** Operation is unimplemented */ - UNIMPLEMENTED (Unimplemented), - /** Operation timeout */ - OPERATIONTIMEOUT (OperationTimeout), - /** Invalid arguments */ - BADARGUMENTS (BadArguments), - - /** API errors. - * This is never thrown by the server, it shouldn't be used other than - * to indicate a range. Specifically error codes greater than this - * value are API errors (while values less than this indicate a - * {@link #SYSTEMERROR}). - */ - APIERROR (APIError), - - /** Node does not exist */ - NONODE (NoNode), - /** Not authenticated */ - NOAUTH (NoAuth), - /** Version conflict */ - BADVERSION (BadVersion), - /** Ephemeral nodes may not have children */ - NOCHILDRENFOREPHEMERALS (NoChildrenForEphemerals), - /** The node already exists */ - NODEEXISTS (NodeExists), - /** The node has children */ - NOTEMPTY (NotEmpty), - /** The session has been expired by the server */ - SESSIONEXPIRED (SessionExpired), - /** Invalid callback specified */ - INVALIDCALLBACK (InvalidCallback), - /** Invalid ACL specified */ - INVALIDACL (InvalidACL), - /** Client authentication failed */ - AUTHFAILED (AuthFailed), - /** Session moved to another server, so operation is ignored */ - SESSIONMOVED (-118), - /** State-changing request is passed to read-only server */ - NOTREADONLY (-119); - - private static final Map<Integer,Code> lookup - = new HashMap<Integer,Code>(); - - static { - for(Code c : EnumSet.allOf(Code.class)) - lookup.put(c.code, c); - } - - private final int code; - Code(int code) { - this.code = code; - } - - /** - * Get the int value for a particular Code. - * @return error code as integer - */ - public int intValue() { return code; } - - /** - * Get the Code value for a particular integer error code - * @param code int error code - * @return Code value corresponding to specified int code, or null - */ - public static Code get(int code) { - return lookup.get(code); - } - } - - static String getCodeMessage(Code code) { - switch (code) { - case OK: - return "ok"; - case SYSTEMERROR: - return "SystemError"; - case RUNTIMEINCONSISTENCY: - return "RuntimeInconsistency"; - case DATAINCONSISTENCY: - return "DataInconsistency"; - case CONNECTIONLOSS: - return "ConnectionLoss"; - case MARSHALLINGERROR: - return "MarshallingError"; - case UNIMPLEMENTED: - return "Unimplemented"; - case OPERATIONTIMEOUT: - return "OperationTimeout"; - case BADARGUMENTS: - return "BadArguments"; - case APIERROR: - return "APIError"; - case NONODE: - return "NoNode"; - case NOAUTH: - return "NoAuth"; - case BADVERSION: - return "BadVersion"; - case NOCHILDRENFOREPHEMERALS: - return "NoChildrenForEphemerals"; - case NODEEXISTS: - return "NodeExists"; - case INVALIDACL: - return "InvalidACL"; - case AUTHFAILED: - return "AuthFailed"; - case NOTEMPTY: - return "Directory not empty"; - case SESSIONEXPIRED: - return "Session expired"; - case INVALIDCALLBACK: - return "Invalid callback"; - case SESSIONMOVED: - return "Session moved"; - case NOTREADONLY: - return "Not a read-only call"; - default: - return "Unknown error " + code; - } - } - - private Code code; - - private String path; - - public KeeperException(Code code) { - this.code = code; - } - - KeeperException(Code code, String path) { - this.code = code; - this.path = path; - } - - /** - * Read the error code for this exception - * @return the error code for this exception - * @deprecated deprecated in 3.1.0, use {@link #code()} instead - */ - @Deprecated - public int getCode() { - return code.code; - } - - /** - * Read the error Code for this exception - * @return the error Code for this exception - */ - public Code code() { - return code; - } - - /** - * Read the path for this exception - * @return the path associated with this error, null if none - */ - public String getPath() { - return path; - } - - @Override - public String getMessage() { - if (path == null) { - return "KeeperErrorCode = " + getCodeMessage(code); - } - return "KeeperErrorCode = " + getCodeMessage(code) + " for " + path; - } - - void setMultiResults(List<OpResult> results) { - this.results = results; - } - - /** - * If this exception was thrown by a multi-request then the (partial) results - * and error codes can be retrieved using this getter. - * @return A copy of the list of results from the operations in the multi-request. - * - * @since 3.4.0 - * - */ - public List<OpResult> getResults() { - return results != null ? new ArrayList<OpResult>(results) : null; - } - - /** - * @see Code#APIERROR - */ - @InterfaceAudience.Public - public static class APIErrorException extends KeeperException { - public APIErrorException() { - super(Code.APIERROR); - } - } - - /** - * @see Code#AUTHFAILED - */ - @InterfaceAudience.Public - public static class AuthFailedException extends KeeperException { - public AuthFailedException() { - super(Code.AUTHFAILED); - } - } - - /** - * @see Code#BADARGUMENTS - */ - @InterfaceAudience.Public - public static class BadArgumentsException extends KeeperException { - public BadArgumentsException() { - super(Code.BADARGUMENTS); - } - public BadArgumentsException(String path) { - super(Code.BADARGUMENTS, path); - } - } - - /** - * @see Code#BADVERSION - */ - @InterfaceAudience.Public - public static class BadVersionException extends KeeperException { - public BadVersionException() { - super(Code.BADVERSION); - } - public BadVersionException(String path) { - super(Code.BADVERSION, path); - } - } - - /** - * @see Code#CONNECTIONLOSS - */ - @InterfaceAudience.Public - public static class ConnectionLossException extends KeeperException { - public ConnectionLossException() { - super(Code.CONNECTIONLOSS); - } - } - - /** - * @see Code#DATAINCONSISTENCY - */ - @InterfaceAudience.Public - public static class DataInconsistencyException extends KeeperException { - public DataInconsistencyException() { - super(Code.DATAINCONSISTENCY); - } - } - - /** - * @see Code#INVALIDACL - */ - @InterfaceAudience.Public - public static class InvalidACLException extends KeeperException { - public InvalidACLException() { - super(Code.INVALIDACL); - } - public InvalidACLException(String path) { - super(Code.INVALIDACL, path); - } - } - - /** - * @see Code#INVALIDCALLBACK - */ - @InterfaceAudience.Public - public static class InvalidCallbackException extends KeeperException { - public InvalidCallbackException() { - super(Code.INVALIDCALLBACK); - } - } - - /** - * @see Code#MARSHALLINGERROR - */ - @InterfaceAudience.Public - public static class MarshallingErrorException extends KeeperException { - public MarshallingErrorException() { - super(Code.MARSHALLINGERROR); - } - } - - /** - * @see Code#NOAUTH - */ - @InterfaceAudience.Public - public static class NoAuthException extends KeeperException { - public NoAuthException() { - super(Code.NOAUTH); - } - } - - /** - * @see Code#NOCHILDRENFOREPHEMERALS - */ - @InterfaceAudience.Public - public static class NoChildrenForEphemeralsException extends KeeperException { - public NoChildrenForEphemeralsException() { - super(Code.NOCHILDRENFOREPHEMERALS); - } - public NoChildrenForEphemeralsException(String path) { - super(Code.NOCHILDRENFOREPHEMERALS, path); - } - } - - /** - * @see Code#NODEEXISTS - */ - @InterfaceAudience.Public - public static class NodeExistsException extends KeeperException { - public NodeExistsException() { - super(Code.NODEEXISTS); - } - public NodeExistsException(String path) { - super(Code.NODEEXISTS, path); - } - } - - /** - * @see Code#NONODE - */ - @InterfaceAudience.Public - public static class NoNodeException extends KeeperException { - public NoNodeException() { - super(Code.NONODE); - } - public NoNodeException(String path) { - super(Code.NONODE, path); - } - } - - /** - * @see Code#NOTEMPTY - */ - @InterfaceAudience.Public - public static class NotEmptyException extends KeeperException { - public NotEmptyException() { - super(Code.NOTEMPTY); - } - public NotEmptyException(String path) { - super(Code.NOTEMPTY, path); - } - } - - /** - * @see Code#OPERATIONTIMEOUT - */ - @InterfaceAudience.Public - public static class OperationTimeoutException extends KeeperException { - public OperationTimeoutException() { - super(Code.OPERATIONTIMEOUT); - } - } - - /** - * @see Code#RUNTIMEINCONSISTENCY - */ - @InterfaceAudience.Public - public static class RuntimeInconsistencyException extends KeeperException { - public RuntimeInconsistencyException() { - super(Code.RUNTIMEINCONSISTENCY); - } - } - - /** - * @see Code#SESSIONEXPIRED - */ - @InterfaceAudience.Public - public static class SessionExpiredException extends KeeperException { - public SessionExpiredException() { - super(Code.SESSIONEXPIRED); - } - } - - /** - * @see Code#SESSIONMOVED - */ - @InterfaceAudience.Public - public static class SessionMovedException extends KeeperException { - public SessionMovedException() { - super(Code.SESSIONMOVED); - } - } - - /** - * @see Code#NOTREADONLY - */ - @InterfaceAudience.Public - public static class NotReadOnlyException extends KeeperException { - public NotReadOnlyException() { - super(Code.NOTREADONLY); - } - } - - /** - * @see Code#SYSTEMERROR - */ - @InterfaceAudience.Public - public static class SystemErrorException extends KeeperException { - public SystemErrorException() { - super(Code.SYSTEMERROR); - } - } - - /** - * @see Code#UNIMPLEMENTED - */ - @InterfaceAudience.Public - public static class UnimplementedException extends KeeperException { - public UnimplementedException() { - super(Code.UNIMPLEMENTED); - } - } -} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java b/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java deleted file mode 100644 index c4975be..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/Login.java +++ /dev/null @@ -1,407 +0,0 @@ -/** - * 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.zookeeper; - -/** - * This class is responsible for refreshing Kerberos credentials for - * logins for both Zookeeper client and server. - * See ZooKeeperSaslServer for server-side usage. - * See ZooKeeperSaslClient for client-side usage. - */ - -import javax.security.auth.kerberos.KerberosPrincipal; -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.security.auth.callback.CallbackHandler; - -import org.apache.zookeeper.client.ZooKeeperSaslClient; -import org.apache.zookeeper.common.Time; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import javax.security.auth.kerberos.KerberosTicket; -import javax.security.auth.Subject; -import java.util.Date; -import java.util.Random; -import java.util.Set; - -public class Login { - private static final Logger LOG = LoggerFactory.getLogger(Login.class); - public CallbackHandler callbackHandler; - - // LoginThread will sleep until 80% of time from last refresh to - // ticket's expiry has been reached, at which time it will wake - // and try to renew the ticket. - private static final float TICKET_RENEW_WINDOW = 0.80f; - - /** - * Percentage of random jitter added to the renewal time - */ - private static final float TICKET_RENEW_JITTER = 0.05f; - - // Regardless of TICKET_RENEW_WINDOW setting above and the ticket expiry time, - // thread will not sleep between refresh attempts any less than 1 minute (60*1000 milliseconds = 1 minute). - // Change the '1' to e.g. 5, to change this to 5 minutes. - private static final long MIN_TIME_BEFORE_RELOGIN = 1 * 60 * 1000L; - - private Subject subject = null; - private Thread t = null; - private boolean isKrbTicket = false; - private boolean isUsingTicketCache = false; - private boolean isUsingKeytab = false; - - /** Random number generator */ - private static Random rng = new Random(); - - private LoginContext login = null; - private String loginContextName = null; - private String keytabFile = null; - private String principal = null; - - // Initialize 'lastLogin' to do a login at first time - private long lastLogin = Time.currentElapsedTime() - MIN_TIME_BEFORE_RELOGIN; - - /** - * LoginThread constructor. The constructor starts the thread used - * to periodically re-login to the Kerberos Ticket Granting Server. - * @param loginContextName - * name of section in JAAS file that will be use to login. - * Passed as first param to javax.security.auth.login.LoginContext(). - * - * @param callbackHandler - * Passed as second param to javax.security.auth.login.LoginContext(). - * @throws javax.security.auth.login.LoginException - * Thrown if authentication fails. - */ - public Login(final String loginContextName, CallbackHandler callbackHandler) - throws LoginException { - this.callbackHandler = callbackHandler; - login = login(loginContextName); - this.loginContextName = loginContextName; - subject = login.getSubject(); - isKrbTicket = !subject.getPrivateCredentials(KerberosTicket.class).isEmpty(); - AppConfigurationEntry entries[] = Configuration.getConfiguration().getAppConfigurationEntry(loginContextName); - for (AppConfigurationEntry entry: entries) { - // there will only be a single entry, so this for() loop will only be iterated through once. - if (entry.getOptions().get("useTicketCache") != null) { - String val = (String)entry.getOptions().get("useTicketCache"); - if (val.equals("true")) { - isUsingTicketCache = true; - } - } - if (entry.getOptions().get("keyTab") != null) { - keytabFile = (String)entry.getOptions().get("keyTab"); - isUsingKeytab = true; - } - if (entry.getOptions().get("principal") != null) { - principal = (String)entry.getOptions().get("principal"); - } - break; - } - - if (!isKrbTicket) { - // if no TGT, do not bother with ticket management. - return; - } - - // Refresh the Ticket Granting Ticket (TGT) periodically. How often to refresh is determined by the - // TGT's existing expiry date and the configured MIN_TIME_BEFORE_RELOGIN. For testing and development, - // you can decrease the interval of expiration of tickets (for example, to 3 minutes) by running : - // "modprinc -maxlife 3mins <principal>" in kadmin. - t = new Thread(new Runnable() { - public void run() { - LOG.info("TGT refresh thread started."); - while (true) { // renewal thread's main loop. if it exits from here, thread will exit. - KerberosTicket tgt = getTGT(); - long now = Time.currentWallTime(); - long nextRefresh; - Date nextRefreshDate; - if (tgt == null) { - nextRefresh = now + MIN_TIME_BEFORE_RELOGIN; - nextRefreshDate = new Date(nextRefresh); - LOG.warn("No TGT found: will try again at " + nextRefreshDate); - } else { - nextRefresh = getRefreshTime(tgt); - long expiry = tgt.getEndTime().getTime(); - Date expiryDate = new Date(expiry); - if ((isUsingTicketCache) && (tgt.getEndTime().equals(tgt.getRenewTill()))) { - LOG.error("The TGT cannot be renewed beyond the next expiry date: " + expiryDate + "." + - "This process will not be able to authenticate new SASL connections after that " + - "time (for example, it will not be authenticate a new connection with a Zookeeper " + - "Quorum member). Ask your system administrator to either increase the " + - "'renew until' time by doing : 'modprinc -maxrenewlife " + principal + "' within " + - "kadmin, or instead, to generate a keytab for " + principal + ". Because the TGT's " + - "expiry cannot be further extended by refreshing, exiting refresh thread now."); - return; - } - // determine how long to sleep from looking at ticket's expiry. - // We should not allow the ticket to expire, but we should take into consideration - // MIN_TIME_BEFORE_RELOGIN. Will not sleep less than MIN_TIME_BEFORE_RELOGIN, unless doing so - // would cause ticket expiration. - if ((nextRefresh > expiry) || - ((now + MIN_TIME_BEFORE_RELOGIN) > expiry)) { - // expiry is before next scheduled refresh). - nextRefresh = now; - } else { - if (nextRefresh < (now + MIN_TIME_BEFORE_RELOGIN)) { - // next scheduled refresh is sooner than (now + MIN_TIME_BEFORE_LOGIN). - Date until = new Date(nextRefresh); - Date newuntil = new Date(now + MIN_TIME_BEFORE_RELOGIN); - LOG.warn("TGT refresh thread time adjusted from : " + until + " to : " + newuntil + " since " - + "the former is sooner than the minimum refresh interval (" - + MIN_TIME_BEFORE_RELOGIN / 1000 + " seconds) from now."); - } - nextRefresh = Math.max(nextRefresh, now + MIN_TIME_BEFORE_RELOGIN); - } - nextRefreshDate = new Date(nextRefresh); - if (nextRefresh > expiry) { - LOG.error("next refresh: " + nextRefreshDate + " is later than expiry " + expiryDate - + ". This may indicate a clock skew problem. Check that this host and the KDC's " - + "hosts' clocks are in sync. Exiting refresh thread."); - return; - } - } - if (now == nextRefresh) { - LOG.info("refreshing now because expiry is before next scheduled refresh time."); - } else if (now < nextRefresh) { - Date until = new Date(nextRefresh); - LOG.info("TGT refresh sleeping until: " + until.toString()); - try { - Thread.sleep(nextRefresh - now); - } catch (InterruptedException ie) { - LOG.warn("TGT renewal thread has been interrupted and will exit."); - break; - } - } - else { - LOG.error("nextRefresh:" + nextRefreshDate + " is in the past: exiting refresh thread. Check" - + " clock sync between this host and KDC - (KDC's clock is likely ahead of this host)." - + " Manual intervention will be required for this client to successfully authenticate." - + " Exiting refresh thread."); - break; - } - if (isUsingTicketCache) { - String cmd = "/usr/bin/kinit"; - if (System.getProperty("zookeeper.kinit") != null) { - cmd = System.getProperty("zookeeper.kinit"); - } - String kinitArgs = "-R"; - int retry = 1; - while (retry >= 0) { - try { - LOG.debug("running ticket cache refresh command: " + cmd + " " + kinitArgs); - Shell.execCommand(cmd, kinitArgs); - break; - } catch (Exception e) { - if (retry > 0) { - --retry; - // sleep for 10 seconds - try { - Thread.sleep(10 * 1000); - } catch (InterruptedException ie) { - LOG.error("Interrupted while renewing TGT, exiting Login thread"); - return; - } - } else { - LOG.warn("Could not renew TGT due to problem running shell command: '" + cmd - + " " + kinitArgs + "'" + "; exception was:" + e + ". Exiting refresh thread.",e); - return; - } - } - } - } - try { - int retry = 1; - while (retry >= 0) { - try { - reLogin(); - break; - } catch (LoginException le) { - if (retry > 0) { - --retry; - // sleep for 10 seconds. - try { - Thread.sleep(10 * 1000); - } catch (InterruptedException e) { - LOG.error("Interrupted during login retry after LoginException:", le); - throw le; - } - } else { - LOG.error("Could not refresh TGT for principal: " + principal + ".", le); - } - } - } - } catch (LoginException le) { - LOG.error("Failed to refresh TGT: refresh thread exiting now.",le); - break; - } - } - } - }); - t.setDaemon(true); - } - - public void startThreadIfNeeded() { - // thread object 't' will be null if a refresh thread is not needed. - if (t != null) { - t.start(); - } - } - - public void shutdown() { - if ((t != null) && (t.isAlive())) { - t.interrupt(); - try { - t.join(); - } catch (InterruptedException e) { - LOG.warn("error while waiting for Login thread to shutdown: " + e); - } - } - } - - public Subject getSubject() { - return subject; - } - - public String getLoginContextName() { - return loginContextName; - } - - private synchronized LoginContext login(final String loginContextName) throws LoginException { - if (loginContextName == null) { - throw new LoginException("loginContext name (JAAS file section header) was null. " + - "Please check your java.security.login.auth.config (=" + - System.getProperty("java.security.login.auth.config") + - ") and your " + ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY + "(=" + - System.getProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, "Client") + ")"); - } - LoginContext loginContext = new LoginContext(loginContextName,callbackHandler); - loginContext.login(); - LOG.info("{} successfully logged in.", loginContextName); - return loginContext; - } - - // c.f. org.apache.hadoop.security.UserGroupInformation. - private long getRefreshTime(KerberosTicket tgt) { - long start = tgt.getStartTime().getTime(); - long expires = tgt.getEndTime().getTime(); - LOG.info("TGT valid starting at: " + tgt.getStartTime().toString()); - LOG.info("TGT expires: " + tgt.getEndTime().toString()); - long proposedRefresh = start + (long) ((expires - start) * - (TICKET_RENEW_WINDOW + (TICKET_RENEW_JITTER * rng.nextDouble()))); - if (proposedRefresh > expires) { - // proposedRefresh is too far in the future: it's after ticket expires: simply return now. - return Time.currentWallTime(); - } - else { - return proposedRefresh; - } - } - - private synchronized KerberosTicket getTGT() { - Set<KerberosTicket> tickets = subject.getPrivateCredentials(KerberosTicket.class); - for(KerberosTicket ticket: tickets) { - KerberosPrincipal server = ticket.getServer(); - if (server.getName().equals("krbtgt/" + server.getRealm() + "@" + server.getRealm())) { - LOG.debug("Client principal is \"" + ticket.getClient().getName() + "\"."); - LOG.debug("Server principal is \"" + ticket.getServer().getName() + "\"."); - return ticket; - } - } - return null; - } - - private boolean hasSufficientTimeElapsed() { - long now = Time.currentElapsedTime(); - if (now - getLastLogin() < MIN_TIME_BEFORE_RELOGIN ) { - LOG.warn("Not attempting to re-login since the last re-login was " + - "attempted less than " + (MIN_TIME_BEFORE_RELOGIN/1000) + " seconds"+ - " before."); - return false; - } - // register most recent relogin attempt - setLastLogin(now); - return true; - } - - /** - * Returns login object - * @return login - */ - private LoginContext getLogin() { - return login; - } - - /** - * Set the login object - * @param login - */ - private void setLogin(LoginContext login) { - this.login = login; - } - - /** - * Set the last login time. - * @param time the number of milliseconds since the beginning of time - */ - private void setLastLogin(long time) { - lastLogin = time; - } - - /** - * Get the time of the last login. - * @return the number of milliseconds since the beginning of time. - */ - private long getLastLogin() { - return lastLogin; - } - - /** - * Re-login a principal. This method assumes that {@link #login(String)} has happened already. - * @throws javax.security.auth.login.LoginException on a failure - */ - // c.f. HADOOP-6559 - private synchronized void reLogin() - throws LoginException { - if (!isKrbTicket) { - return; - } - LoginContext login = getLogin(); - if (login == null) { - throw new LoginException("login must be done first"); - } - if (!hasSufficientTimeElapsed()) { - return; - } - LOG.info("Initiating logout for " + principal); - synchronized (Login.class) { - //clear up the kerberos state. But the tokens are not cleared! As per - //the Java kerberos login module code, only the kerberos credentials - //are cleared - login.logout(); - //login and also update the subject field of this instance to - //have the new credentials (pass it to the LoginContext constructor) - login = new LoginContext(loginContextName, getSubject()); - LOG.info("Initiating re-login for " + principal); - login.login(); - setLogin(login); - } - } -} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java b/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java deleted file mode 100644 index 70f7623..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiResponse.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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.zookeeper; - -import org.apache.jute.InputArchive; -import org.apache.jute.OutputArchive; -import org.apache.jute.Record; -import org.apache.zookeeper.proto.CreateResponse; -import org.apache.zookeeper.proto.MultiHeader; -import org.apache.zookeeper.proto.SetDataResponse; -import org.apache.zookeeper.proto.ErrorResponse; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Handles the response from a multi request. Such a response consists of - * a sequence of responses each prefixed by a MultiResponse that indicates - * the type of the response. The end of the list is indicated by a MultiHeader - * with a negative type. Each individual response is in the same format as - * with the corresponding operation in the original request list. - */ -public class MultiResponse implements Record, Iterable<OpResult> { - private List<OpResult> results = new ArrayList<OpResult>(); - - public void add(OpResult x) { - results.add(x); - } - - @Override - public Iterator<OpResult> iterator() { - return results.iterator(); - } - - public int size() { - return results.size(); - } - - @Override - public void serialize(OutputArchive archive, String tag) throws IOException { - archive.startRecord(this, tag); - - int index = 0; - for (OpResult result : results) { - int err = result.getType() == ZooDefs.OpCode.error ? ((OpResult.ErrorResult)result).getErr() : 0; - - new MultiHeader(result.getType(), false, err).serialize(archive, tag); - - switch (result.getType()) { - case ZooDefs.OpCode.create: - new CreateResponse(((OpResult.CreateResult) result).getPath()).serialize(archive, tag); - break; - case ZooDefs.OpCode.delete: - case ZooDefs.OpCode.check: - break; - case ZooDefs.OpCode.setData: - new SetDataResponse(((OpResult.SetDataResult) result).getStat()).serialize(archive, tag); - break; - case ZooDefs.OpCode.error: - new ErrorResponse(((OpResult.ErrorResult) result).getErr()).serialize(archive, tag); - break; - default: - throw new IOException("Invalid type " + result.getType() + " in MultiResponse"); - } - } - new MultiHeader(-1, true, -1).serialize(archive, tag); - archive.endRecord(this, tag); - } - - @Override - public void deserialize(InputArchive archive, String tag) throws IOException { - results = new ArrayList<OpResult>(); - - archive.startRecord(tag); - MultiHeader h = new MultiHeader(); - h.deserialize(archive, tag); - while (!h.getDone()) { - switch (h.getType()) { - case ZooDefs.OpCode.create: - CreateResponse cr = new CreateResponse(); - cr.deserialize(archive, tag); - results.add(new OpResult.CreateResult(cr.getPath())); - break; - - case ZooDefs.OpCode.delete: - results.add(new OpResult.DeleteResult()); - break; - - case ZooDefs.OpCode.setData: - SetDataResponse sdr = new SetDataResponse(); - sdr.deserialize(archive, tag); - results.add(new OpResult.SetDataResult(sdr.getStat())); - break; - - case ZooDefs.OpCode.check: - results.add(new OpResult.CheckResult()); - break; - - case ZooDefs.OpCode.error: - //FIXME: need way to more cleanly serialize/deserialize exceptions - ErrorResponse er = new ErrorResponse(); - er.deserialize(archive, tag); - results.add(new OpResult.ErrorResult(er.getErr())); - break; - - default: - throw new IOException("Invalid type " + h.getType() + " in MultiResponse"); - } - h.deserialize(archive, tag); - } - archive.endRecord(tag); - } - - public List<OpResult> getResultList() { - return results; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MultiResponse)) return false; - - MultiResponse other = (MultiResponse) o; - - if (results != null) { - Iterator<OpResult> i = other.results.iterator(); - for (OpResult result : results) { - if (i.hasNext()) { - if (!result.equals(i.next())) { - return false; - } - } else { - return false; - } - } - return !i.hasNext(); - } - else return other.results == null; - } - - @Override - public int hashCode() { - int hash = results.size(); - for (OpResult result : results) { - hash = (hash * 35) + result.hashCode(); - } - return hash; - } -} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/7291e47c/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java ---------------------------------------------------------------------- diff --git a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java b/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java deleted file mode 100644 index 801969a..0000000 --- a/zookeeper-common/src/main/java/org/apache/zookeeper/MultiTransactionRecord.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.zookeeper; - -import org.apache.jute.InputArchive; -import org.apache.jute.OutputArchive; -import org.apache.jute.Record; -import org.apache.zookeeper.proto.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Encodes a composite transaction. In the wire format, each transaction - * consists of a single MultiHeader followed by the appropriate request. - * Each of these MultiHeaders has a type which indicates - * the type of the following transaction or a negative number if no more transactions - * are included. - */ -public class MultiTransactionRecord implements Record, Iterable<Op> { - private List<Op> ops = new ArrayList<Op>(); - - public MultiTransactionRecord() { - } - - public MultiTransactionRecord(Iterable<Op> ops) { - for (Op op : ops) { - add(op); - } - } - - @Override - public Iterator<Op> iterator() { - return ops.iterator() ; - } - - public void add(Op op) { - ops.add(op); - } - - public int size() { - return ops.size(); - } - - @Override - public void serialize(OutputArchive archive, String tag) throws IOException { - archive.startRecord(this, tag); - int index = 0 ; - for (Op op : ops) { - MultiHeader h = new MultiHeader(op.getType(), false, -1); - h.serialize(archive, tag); - switch (op.getType()) { - case ZooDefs.OpCode.create: - op.toRequestRecord().serialize(archive, tag); - break; - case ZooDefs.OpCode.delete: - op.toRequestRecord().serialize(archive, tag); - break; - case ZooDefs.OpCode.setData: - op.toRequestRecord().serialize(archive, tag); - break; - case ZooDefs.OpCode.check: - op.toRequestRecord().serialize(archive, tag); - break; - default: - throw new IOException("Invalid type of op"); - } - } - new MultiHeader(-1, true, -1).serialize(archive, tag); - archive.endRecord(this, tag); - } - - @Override - public void deserialize(InputArchive archive, String tag) throws IOException { - archive.startRecord(tag); - MultiHeader h = new MultiHeader(); - h.deserialize(archive, tag); - - while (!h.getDone()) { - switch (h.getType()) { - case ZooDefs.OpCode.create: - CreateRequest cr = new CreateRequest(); - cr.deserialize(archive, tag); - add(Op.create(cr.getPath(), cr.getData(), cr.getAcl(), cr.getFlags())); - break; - case ZooDefs.OpCode.delete: - DeleteRequest dr = new DeleteRequest(); - dr.deserialize(archive, tag); - add(Op.delete(dr.getPath(), dr.getVersion())); - break; - case ZooDefs.OpCode.setData: - SetDataRequest sdr = new SetDataRequest(); - sdr.deserialize(archive, tag); - add(Op.setData(sdr.getPath(), sdr.getData(), sdr.getVersion())); - break; - case ZooDefs.OpCode.check: - CheckVersionRequest cvr = new CheckVersionRequest(); - cvr.deserialize(archive, tag); - add(Op.check(cvr.getPath(), cvr.getVersion())); - break; - default: - throw new IOException("Invalid type of op"); - } - h.deserialize(archive, tag); - } - archive.endRecord(tag); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MultiTransactionRecord)) return false; - - MultiTransactionRecord that = (MultiTransactionRecord) o; - - if (ops != null) { - Iterator<Op> other = that.ops.iterator(); - for (Op op : ops) { - boolean hasMoreData = other.hasNext(); - if (!hasMoreData) { - return false; - } - Op otherOp = other.next(); - if (!op.equals(otherOp)) { - return false; - } - } - return !other.hasNext(); - } else { - return that.ops == null; - } - - } - - @Override - public int hashCode() { - int h = 1023; - for (Op op : ops) { - h = h * 25 + op.hashCode(); - } - return h; - } -}