View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.zookeeper;
21  
22  import java.util.concurrent.CountDownLatch;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.classification.InterfaceAudience;
27  import org.apache.zookeeper.KeeperException;
28  
29  /**
30   * A ZooKeeper watcher meant to detect deletions of ZNodes.
31   */
32  @InterfaceAudience.Private
33  public class DeletionListener extends ZooKeeperListener {
34  
35    private static final Log LOG = LogFactory.getLog(DeletionListener.class);
36  
37    private final String pathToWatch;
38    private final CountDownLatch deletedLatch;
39  
40    private volatile Throwable exception;
41  
42    /**
43     * Create a new instance of the deletion watcher.
44     * @param zkWatcher ZookeeperWatcher instance
45     * @param pathToWatch (Fully qualified) ZNode path that we are waiting to
46     *                    be deleted.
47     * @param deletedLatch Count down on this latch when deletion has occured.
48     */
49    public DeletionListener(ZooKeeperWatcher zkWatcher, String pathToWatch,
50        CountDownLatch deletedLatch) {
51      super(zkWatcher);
52      this.pathToWatch = pathToWatch;
53      this.deletedLatch = deletedLatch;
54      exception = null;
55    }
56  
57    /**
58     * Check if an exception has occurred when re-setting the watch.
59     * @return True if we were unable to re-set a watch on a ZNode due to
60     *         an exception.
61     */
62    public boolean hasException() {
63      return exception != null;
64    }
65  
66    /**
67     * Get the last exception which has occurred when re-setting the watch.
68     * Use hasException() to check whether or not an exception has occurred.
69     * @return The last exception observed when re-setting the watch.
70     */
71    public Throwable getException() {
72      return exception;
73    }
74  
75    @Override
76    public void nodeDataChanged(String path) {
77      if (!path.equals(pathToWatch)) {
78        return;
79      }
80      try {
81        if (!(ZKUtil.setWatchIfNodeExists(watcher, pathToWatch))) {
82          deletedLatch.countDown();
83        }
84      } catch (KeeperException ex) {
85        exception = ex;
86        deletedLatch.countDown();
87        LOG.error("Error when re-setting the watch on " + pathToWatch, ex);
88      }
89    }
90  
91    @Override
92    public void nodeDeleted(String path) {
93      if (!path.equals(pathToWatch)) {
94        return;
95      }
96      if (LOG.isDebugEnabled()) {
97        LOG.debug("Processing delete on " + pathToWatch);
98      }
99      deletedLatch.countDown();
100   }
101 }