View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.zookeeper;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.concurrent.atomic.AtomicBoolean;
24  
25  import org.apache.zookeeper.CreateMode;
26  import org.apache.zookeeper.KeeperException;
27  import org.apache.zookeeper.KeeperException.AuthFailedException;
28  import org.apache.zookeeper.Watcher;
29  import org.apache.zookeeper.ZooKeeper;
30  import org.apache.zookeeper.data.ACL;
31  import org.apache.zookeeper.data.Stat;
32  
33  /**
34   * A wrapper around {@link ZooKeeper} which tries to mimic semantics around AUTH_FAILED. When
35   * an AuthFailedException is thrown the first time, it is thrown every time after that.
36   */
37  public class AuthFailingZooKeeper extends ZooKeeper {
38    private static final AuthFailedException AUTH_FAILED_EXCEPTION = new AuthFailedException();
39  
40    // Latch for the "first" AUTH_FAILED occurrence
41    private final AtomicBoolean FAILURE_LATCH = new AtomicBoolean(false);
42    // Latch for when we start always throwing AUTH_FAILED
43    private final AtomicBoolean IS_AUTH_FAILED = new AtomicBoolean(false);
44  
45    public AuthFailingZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
46          throws IOException {
47      super(connectString, sessionTimeout, watcher);
48    }
49  
50    /**
51     * Causes AUTH_FAILED exceptions to be thrown by {@code this}.
52     */
53    public void triggerAuthFailed() {
54      FAILURE_LATCH.set(true);
55    }
56  
57    void check() throws KeeperException {
58      // ZK state model states that once an AUTH_FAILED exception is thrown, it is thrown for
59      // every subsequent operation
60      if (IS_AUTH_FAILED.get()) {
61        throw AUTH_FAILED_EXCEPTION;
62      }
63      // We're not yet throwing AUTH_FAILED
64      if (!FAILURE_LATCH.get()) {
65        return;
66      }
67      // Start throwing AUTH_FAILED
68      IS_AUTH_FAILED.set(true);
69      throw AUTH_FAILED_EXCEPTION;
70    }
71  
72    @Override
73    public byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException,
74        InterruptedException {
75      check();
76      return super.getData(path, watcher, stat);
77    }
78  
79    @Override
80    public String create(String path, byte[] data, List<ACL> acl, CreateMode cmode)
81        throws KeeperException, InterruptedException {
82      check();
83      return super.create(path,  data, acl, cmode);
84    }
85  
86    @Override
87    public Stat exists(String path, boolean watch) throws KeeperException, InterruptedException {
88      check();
89      return super.exists(path, watch);
90    }
91  
92    @Override
93    public Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException {
94      check();
95      return super.exists(path, watcher);
96    }
97  
98    @Override
99    public List<String> getChildren(String path, boolean watch)
100       throws KeeperException, InterruptedException {
101     check();
102     return super.getChildren(path, watch);
103   }
104 }