Ejemplo n.º 1
0
    def get_children(self, path, watch=None, include_data=False):
        self.verify()
        if not isinstance(path, six.string_types):
            raise TypeError("path must be a string")

        def clean_path(p):
            return p.strip("/")

        path = utils.normpath(path)
        with self.storage.lock:
            if path not in self.storage:
                raise k_exceptions.NoNodeError("Node %s does not exist" %
                                               (path))
            paths = self.storage.get_children(path)
        if watch:
            with self._watches_lock:
                self._child_watchers[path].append(watch)
        if include_data:
            children_with_data = []
            for (child_path, data) in six.iteritems(paths):
                child_path = clean_path(child_path[len(path):])
                children_with_data.append((child_path, data))
            return children_with_data
        else:
            children = []
            for child_path in six.iterkeys(paths):
                child_path = clean_path(child_path[len(path):])
                children.append(child_path)
            return children
Ejemplo n.º 2
0
    def create(self,
               path,
               value=b"",
               sequence=False,
               ephemeral=False,
               session_id=None):
        def sequence_iter(path, parent_path):
            for i in itertools.count(0):
                sequence_id = self._sequences.get(parent_path, 0)
                if sequence_id == SEQ_ROLLOVER:
                    self._sequences[parent_path] = SEQ_ROLLOVER_TO
                else:
                    self._sequences[parent_path] = sequence_id + 1
                yield path + '%010d' % (sequence_id)

        parent_path, _node_name = os.path.split(path)
        with self.lock:
            if sequence:
                for possible_path in sequence_iter(path, parent_path):
                    if possible_path not in self:
                        path = possible_path
                        break
            parents = sorted(six.iterkeys(self.get_parents(path)))
            if parent_path not in self:
                if sequence:
                    self._sequences.pop(parent_path, None)
                raise k_exceptions.NoNodeError(
                    "Parent node %s does not exist" % (parent_path))
            if ephemeral and not session_id:
                raise k_exceptions.SystemZookeeperError("Ephemeral node %s can"
                                                        " not be created"
                                                        " without a session"
                                                        " id" % path)
            if path in self:
                raise k_exceptions.NodeExistsError("Node %s already"
                                                   " exists" % (path))
            for parent_path in reversed(parents):
                if self._paths[parent_path]['ephemeral']:
                    raise k_exceptions.NoChildrenForEphemeralsError(
                        "Parent %s is ephemeral" % parent_path)
            path_data = {
                # Kazoo clients expect in milliseconds
                'created_on': utils.millitime(),
                'updated_on': utils.millitime(),
                'version': 0,
                # Not supported for now...
                'aversion': -1,
                'cversion': -1,
                'data': value,
            }
            if ephemeral:
                path_data['ephemeral_owner'] = session_id
                path_data['ephemeral'] = True
            else:
                path_data['ephemeral'] = False
            self._paths[path] = path_data
            return (True, parents, path)
Ejemplo n.º 3
0
 def get(self, path, watch=None):
     self.verify()
     if not isinstance(path, six.string_types):
         raise TypeError("path must be a string")
     path = utils.normpath(path)
     try:
         (data, znode) = self.storage.get(path)
     except KeyError:
         raise k_exceptions.NoNodeError("Node %s does not exist" % (path))
     if watch:
         with self._watches_lock:
             self._data_watchers[path].append(watch)
     return (data, znode)
Ejemplo n.º 4
0
    def test_update_no_node_error(self, mock_create_node_path,
                                  mock_create_node):
        # The first time _create_node() is called, we raise the exception.
        # After that we just return True so that we can pretent like the
        # subsequent calls in _create() work fine.
        mock_create_node.side_effect = [exceptions.NoNodeError('Snap'), True]

        self.reg._update_state(True)

        # The create_node_path method should be executed once.
        mock_create_node_path.assert_called_once_with()

        # The create_node method should be executed twice.
        mock_create_node.assert_called_twice_with()
Ejemplo n.º 5
0
 def delete(self, path, version=-1, recursive=False):
     if not isinstance(path, six.string_types):
         raise TypeError("path must be a string")
     data_watches = []
     child_watches = []
     path = utils.normpath(path)
     with self.storage.lock:
         if path not in self.storage:
             raise k_exceptions.NoNodeError("Node %s does not exist" %
                                            (path))
         path_version = self.storage[path]['version']
         if version != -1 and path_version != version:
             raise k_exceptions.BadVersionError("Version mismatch"
                                                " (%s != %s)" %
                                                (version, path_version))
         if recursive:
             paths = [path]
             children = self.storage.get_children(path, only_direct=False)
             for child_path in six.iterkeys(children):
                 paths.append(child_path)
         else:
             children = self.storage.get_children(path, only_direct=False)
             if children:
                 raise k_exceptions.NotEmptyError("Path %s is not-empty"
                                                  " (%s children exist)" %
                                                  (path, len(children)))
             paths = [path]
         paths = list(reversed(sorted(set(paths))))
         with self.storage.transaction():
             for path in paths:
                 self.storage.pop(path)
             parents = []
             for path in paths:
                 parents.extend(self.storage.get_parents(path))
             parents = list(reversed(sorted(set(parents))))
             for path in parents:
                 event = k_states.WatchedEvent(
                     type=k_states.EventType.DELETED,
                     state=k_states.KeeperState.CONNECTED,
                     path=path)
                 child_watches.append(([path], event))
             for path in paths:
                 event = k_states.WatchedEvent(
                     type=k_states.EventType.DELETED,
                     state=k_states.KeeperState.CONNECTED,
                     path=path)
                 data_watches.append(([path], event))
     return (True, data_watches, child_watches)
Ejemplo n.º 6
0
 def set(self, path, value, version=-1):
     if not isinstance(path, six.string_types):
         raise TypeError("path must be a string")
     if not isinstance(value, six.binary_type):
         raise TypeError("value must be a byte string")
     if not isinstance(version, int):
         raise TypeError("version must be an int")
     path = utils.normpath(path)
     try:
         stat = self.storage.set(path, value, version=version)
     except KeyError:
         raise k_exceptions.NoNodeError("Node %s does not exist" % (path))
     data_watches = []
     child_watches = []
     event = k_states.WatchedEvent(type=k_states.EventType.CHANGED,
                                   state=k_states.KeeperState.CONNECTED,
                                   path=path)
     data_watches.append(([path], event))
     return (stat, data_watches, child_watches)
Ejemplo n.º 7
0
 def commit(self):
     self._check_tx_state()
     self._client.verify()
     with try_txn_lock(self._lock):
         self._check_tx_state()
         # Delay all watch firing until we are sure that it succeeded.
         results = []
         child_watches = []
         data_watches = []
         try:
             with self._storage.transaction():
                 for op in self.operations:
                     result = op()
                     results.append(result[0])
                     data_watches.extend(result[1])
                     child_watches.extend(result[2])
         except StopTransaction as e:
             for i in range(0, len(results)):
                 results[i] = k_exceptions.RolledBackError()
             if isinstance(e, StopTransactionBadVersion):
                 results.append(k_exceptions.BadVersionError())
             if isinstance(e, StopTransactionNoExists):
                 results.append(k_exceptions.NoNodeError())
             while len(results) != len(self.operations):
                 results.append(k_exceptions.RuntimeInconsistency())
         except (NotImplementedError, AttributeError, RuntimeError,
                 ValueError, TypeError, k_exceptions.ConnectionClosedError,
                 k_exceptions.SessionExpiredError):
             # Allow all these errors to bubble up.
             six.reraise(*sys.exc_info())
         except Exception as e:
             for i in range(0, len(results)):
                 results[i] = k_exceptions.RolledBackError()
             results.append(e)
             while len(results) != len(self.operations):
                 results.append(k_exceptions.RuntimeInconsistency())
         else:
             self._storage.inform(self._client, child_watches, data_watches)
             self.committed = True
         return results