View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.security.visibility;
19  
20  import java.io.IOException;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.hadoop.classification.InterfaceAudience;
25  import org.apache.hadoop.conf.Configuration;
26  import org.apache.hadoop.hbase.zookeeper.ZKUtil;
27  import org.apache.hadoop.hbase.zookeeper.ZooKeeperListener;
28  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
29  import org.apache.zookeeper.KeeperException;
30  
31  /**
32   * A zk watcher that watches the labels table znode. This would create a znode
33   * /hbase/visibility_labels and will have a serialized form of a set of labels in the system.
34   */
35  @InterfaceAudience.Private
36  public class ZKVisibilityLabelWatcher extends ZooKeeperListener {
37  
38    private static final Log LOG = LogFactory.getLog(ZKVisibilityLabelWatcher.class);
39    private static final String VISIBILITY_LABEL_ZK_PATH = "zookeeper.znode.visibility.label.parent";
40    private static final String DEFAULT_VISIBILITY_LABEL_NODE = "visibility/labels";
41    private static final String VISIBILITY_USER_AUTHS_ZK_PATH = 
42        "zookeeper.znode.visibility.user.auths.parent";
43    private static final String DEFAULT_VISIBILITY_USER_AUTHS_NODE = "visibility/user_auths";
44  
45    private VisibilityLabelsManager labelsManager;
46    private String labelZnode;
47    private String userAuthsZnode;
48  
49    public ZKVisibilityLabelWatcher(ZooKeeperWatcher watcher, VisibilityLabelsManager labelsManager,
50        Configuration conf) {
51      super(watcher);
52      this.labelsManager = labelsManager;
53      String labelZnodeParent = conf.get(VISIBILITY_LABEL_ZK_PATH, DEFAULT_VISIBILITY_LABEL_NODE);
54      String userAuthsZnodeParent = conf.get(VISIBILITY_USER_AUTHS_ZK_PATH,
55          DEFAULT_VISIBILITY_USER_AUTHS_NODE);
56      this.labelZnode = ZKUtil.joinZNode(watcher.baseZNode, labelZnodeParent);
57      this.userAuthsZnode = ZKUtil.joinZNode(watcher.baseZNode, userAuthsZnodeParent);
58    }
59  
60    public void start() throws KeeperException {
61      watcher.registerListener(this);
62      if (ZKUtil.watchAndCheckExists(watcher, labelZnode)) {
63        byte[] data = ZKUtil.getDataAndWatch(watcher, labelZnode);
64        if (data != null) {
65          refreshVisibilityLabelsCache(data);
66        }
67      }
68      if (ZKUtil.watchAndCheckExists(watcher, userAuthsZnode)) {
69        byte[] data = ZKUtil.getDataAndWatch(watcher, userAuthsZnode);
70        if (data != null) {
71          refreshUserAuthsCache(data);
72        }
73      }
74    }
75  
76    private void refreshVisibilityLabelsCache(byte[] data) {
77      try {
78        this.labelsManager.refreshLabelsCache(data);
79      } catch (IOException ioe) {
80        LOG.error("Failed parsing data from labels table " + " from zk", ioe);
81      }
82    }
83  
84    private void refreshUserAuthsCache(byte[] data) {
85      try {
86        this.labelsManager.refreshUserAuthsCache(data);
87      } catch (IOException ioe) {
88        LOG.error("Failed parsing data from labels table " + " from zk", ioe);
89      }
90    }
91  
92    @Override
93    public void nodeCreated(String path) {
94      if (path.equals(labelZnode) || path.equals(userAuthsZnode)) {
95        try {
96          ZKUtil.watchAndCheckExists(watcher, path);
97        } catch (KeeperException ke) {
98          LOG.error("Error setting watcher on node " + path, ke);
99          // only option is to abort
100         watcher.abort("Zookeeper error obtaining label node children", ke);
101       }
102     }
103   }
104 
105   @Override
106   public void nodeDeleted(String path) {
107     // There is no case of visibility labels path to get deleted.
108   }
109 
110   @Override
111   public void nodeDataChanged(String path) {
112     if (path.equals(labelZnode) || path.equals(userAuthsZnode)) {
113       try {
114         watcher.sync(path);
115         byte[] data = ZKUtil.getDataAndWatch(watcher, path);
116         if (path.equals(labelZnode)) {
117           refreshVisibilityLabelsCache(data);
118         } else {
119           refreshUserAuthsCache(data);
120         }
121       } catch (KeeperException ke) {
122         LOG.error("Error reading data from zookeeper for node " + path, ke);
123         // only option is to abort
124         watcher.abort("Zookeeper error getting data for node " + path, ke);
125       }
126     }
127   }
128 
129   @Override
130   public void nodeChildrenChanged(String path) {
131     // We are not dealing with child nodes under the label znode or userauths znode.
132   }
133 
134   /**
135    * Write a labels mirror or user auths mirror into zookeeper
136    * 
137    * @param data
138    * @param labelsOrUserAuths true for writing labels and false for user auths.
139    */
140   public void writeToZookeeper(byte[] data, boolean labelsOrUserAuths) {
141     String znode = this.labelZnode;
142     if (!labelsOrUserAuths) {
143       znode = this.userAuthsZnode;
144     }
145     try {
146       ZKUtil.createWithParents(watcher, znode);
147       ZKUtil.updateExistingNodeData(watcher, znode, data, -1);
148     } catch (KeeperException e) {
149       LOG.error("Failed writing to " + znode, e);
150       watcher.abort("Failed writing node " + znode + " to zookeeper", e);
151     }
152   }
153 }