From: Brian Warner Date: Fri, 9 Nov 2007 09:54:51 +0000 (-0700) Subject: consolidate dirnode/filenode-creation code into Client X-Git-Tag: allmydata-tahoe-0.7.0~236 X-Git-Url: https://git.rkrishnan.org/architecture.txt?a=commitdiff_plain;h=63233ecf37a1ba683d04846ab2b835992017174a;p=tahoe-lafs%2Ftahoe-lafs.git consolidate dirnode/filenode-creation code into Client --- diff --git a/src/allmydata/client.py b/src/allmydata/client.py index 5fde8980..17d411de 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -20,6 +20,12 @@ from allmydata.introducer import IntroducerClient from allmydata.vdrive import VirtualDrive from allmydata.util import hashutil, idlib, testutil +from allmydata.dirnode import FileNode +from allmydata.dirnode2 import NewDirectoryNode +from allmydata.mutable import MutableFileNode +from allmydata.interfaces import IURI, INewDirectoryURI, IDirnodeURI, \ + IFileURI, IMutableFileURI + class Client(node.Node, Referenceable, testutil.PollMixin): implements(RIClient) PORTNUMFILE = "client.port" @@ -209,28 +215,42 @@ class Client(node.Node, Referenceable, testutil.PollMixin): return d + # these four methods are the primitives for creating filenodes and + # dirnodes. The first takes a URI and produces a filenode or (new-style) + # dirnode. The other three create brand-new filenodes/dirnodes. + + def create_node_from_uri(self, u): + # this returns synchronously. As a result, it cannot be used to + # create old-style dirnodes, since those contain a RemoteReference. + # This means that new-style dirnodes cannot contain old-style + # dirnodes as children. + u = IURI(u) + if INewDirectoryURI.providedBy(u): + # new-style dirnodes + return NewDirectoryNode(self).init_from_uri(u) + if IDirnodeURI.providedBy(u): + ## handles old-style dirnodes, both mutable and immutable + #return dirnode.create_directory_node(self, u) + raise RuntimeError("not possible, sorry") + if IFileURI.providedBy(u): + # CHK + return FileNode(u, self) + assert IMutableFileURI.providedBy(u) + return MutableFileNode(self).init_from_uri(u) + def create_empty_dirnode(self): - from allmydata.dirnode2 import NewDirectoryNode n = NewDirectoryNode(self) d = n.create() d.addCallback(lambda res: n) return d - def create_dirnode_from_uri(self, u): - from allmydata.dirnode2 import NewDirectoryNode - return NewDirectoryNode(self).init_from_uri(u) - def create_mutable_file(self, contents=""): - from allmydata.mutable import MutableFileNode n = MutableFileNode(self) d = n.create(contents) d.addCallback(lambda res: n) return d - def create_mutable_file_from_uri(self, u): - from allmydata.mutable import MutableFileNode - return MutableFileNode(self).init_from_uri(u) + def upload(self, uploadable): + uploader = self.getServiceNamed("uploader") + return uploader.upload(uploadable) - def create_file_from_uri(self, u): - from allmydata.mutable import FileNode - return FileNode(u, self) diff --git a/src/allmydata/dirnode.py b/src/allmydata/dirnode.py index dbbe18a3..5b199b04 100644 --- a/src/allmydata/dirnode.py +++ b/src/allmydata/dirnode.py @@ -290,7 +290,7 @@ class ImmutableDirectoryNode: if IDirnodeURI.providedBy(u): return create_directory_node(self._client, u) else: - return defer.succeed(FileNode(u, self._client)) + return defer.succeed(self._client.create_node_from_uri(child_uri)) def _split_uri(self, child_uri): u = IURI(child_uri) diff --git a/src/allmydata/dirnode2.py b/src/allmydata/dirnode2.py index 5cdec394..ec141437 100644 --- a/src/allmydata/dirnode2.py +++ b/src/allmydata/dirnode2.py @@ -5,11 +5,11 @@ from zope.interface import implements from twisted.internet import defer import simplejson from allmydata.interfaces import IMutableFileNode, IDirectoryNode,\ - IMutableFileURI, INewDirectoryURI, IURI, IFileNode, NotMutableError, \ + INewDirectoryURI, IFileNode, NotMutableError, \ IVerifierURI from allmydata.util import hashutil from allmydata.util.hashutil import netstring -from allmydata.dirnode import IntegrityCheckError, FileNode +from allmydata.dirnode import IntegrityCheckError from allmydata.uri import NewDirectoryURI from allmydata.Crypto.Cipher import AES @@ -94,14 +94,7 @@ class NewDirectoryNode: return plaintext def _create_node(self, child_uri): - u = IURI(child_uri) - if INewDirectoryURI.providedBy(u): - return self._client.create_dirnode_from_uri(u) - if IFileNode.providedBy(u): - return self._client.create_file_from_uri(u) - if IMutableFileURI.providedBy(u): - return self._client.create_mutable_file_from_uri(u) - raise TypeError("cannot handle '%s' URI" % (u.__class__,)) + return self._client.create_node_from_uri(child_uri) def _unpack_contents(self, data): # the directory is serialized as a list of netstrings, one per child. @@ -254,10 +247,9 @@ class NewDirectoryNode: the operation completes.""" if self.is_readonly(): return defer.fail(NotMutableError()) - uploader = self._client.getServiceNamed("uploader") - d = uploader.upload(uploadable) - d.addCallback(lambda uri: self.set_node(name, - FileNode(uri, self._client))) + d = self._client.upload(uploadable) + d.addCallback(self._client.create_node_from_uri) + d.addCallback(lambda node: self.set_node(name, node)) return d def delete(self, name): diff --git a/src/allmydata/test/test_dirnode.py b/src/allmydata/test/test_dirnode.py index 3ec6f342..18de497e 100644 --- a/src/allmydata/test/test_dirnode.py +++ b/src/allmydata/test/test_dirnode.py @@ -6,7 +6,7 @@ from twisted.internet import defer from twisted.python import failure from allmydata import uri, dirnode from allmydata.util import hashutil -from allmydata.interfaces import IDirectoryNode, IDirnodeURI +from allmydata.interfaces import IDirectoryNode, IDirnodeURI, IURI, IFileURI from allmydata.scripts import runner from allmydata.dirnode import VirtualDriveServer, \ BadWriteEnablerError, NoPublicRootError @@ -118,6 +118,11 @@ class MyClient: def __init__(self, vds, myfurl): self.tub = MyTub(vds, myfurl) + def create_node_from_uri(self, u): + u = IURI(u) + assert IFileURI.providedBy(u) + return dirnode.FileNode(u, self) + class Test(unittest.TestCase): def test_create_directory(self): basedir = "vdrive/test_create_directory/vdrive" diff --git a/src/allmydata/test/test_mutable.py b/src/allmydata/test/test_mutable.py index f3a7abfc..1499a0d4 100644 --- a/src/allmydata/test/test_mutable.py +++ b/src/allmydata/test/test_mutable.py @@ -7,6 +7,8 @@ from allmydata import mutable, uri, dirnode2 from allmydata.dirnode2 import split_netstring from allmydata.util.hashutil import netstring, tagged_hash from allmydata.encode import NotEnoughPeersError +from allmydata.interfaces import IURI, INewDirectoryURI, IDirnodeURI, \ + IMutableFileURI import sha from allmydata.Crypto.Util.number import bytes_to_long @@ -113,7 +115,21 @@ class MyClient: d = n.create(contents) d.addCallback(lambda res: n) return d - def create_mutable_file_from_uri(self, u): + + def create_node_from_uri(self, u): + # this returns synchronously. As a result, it cannot be used to + # create old-style dirnodes, since those contain a RemoteReference. + # This means that new-style dirnodes cannot contain old-style + # dirnodes as children. + u = IURI(u) + if INewDirectoryURI.providedBy(u): + return self.create_dirnode_from_uri(u) + if IDirnodeURI.providedBy(u): + raise RuntimeError("not possible, sorry") + #if IFileURI.providedBy(u): + # # CHK + # return FileNode(u, self) + assert IMutableFileURI.providedBy(u) return FakeFilenode(self).init_from_uri(u) def get_permuted_peers(self, key, include_myself=True): diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index 8514aca4..20515bcf 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -338,7 +338,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase): # on the same client that uploaded the data. uri = self._mutable_node_1.get_uri() log.msg("starting retrieve1") - newnode = self.clients[0].create_mutable_file_from_uri(uri) + newnode = self.clients[0].create_node_from_uri(uri) return newnode.download_to_data() d.addCallback(_check_download_1) @@ -346,7 +346,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase): self.failUnlessEqual(res, DATA) # same thing, but with a different client uri = self._mutable_node_1.get_uri() - newnode = self.clients[1].create_mutable_file_from_uri(uri) + newnode = self.clients[1].create_node_from_uri(uri) log.msg("starting retrieve2") d1 = newnode.download_to_data() d1.addCallback(lambda res: (res, newnode)) @@ -367,8 +367,8 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase): # now create an even newer node and replace the data on it. This # new node has never been used for download before. uri = self._mutable_node_1.get_uri() - newnode1 = self.clients[2].create_mutable_file_from_uri(uri) - newnode2 = self.clients[3].create_mutable_file_from_uri(uri) + newnode1 = self.clients[2].create_node_from_uri(uri) + newnode2 = self.clients[3].create_node_from_uri(uri) log.msg("starting replace2") d1 = newnode1.replace(NEWERDATA) d1.addCallback(lambda res: newnode2.download_to_data())