class JsonRpcTCPClient(JsonRPCBase): def __init__(self, host, portnumber, delay=0, workers=5, debug=1): JsonRPCBase.__init__(self, workers=workers, debug=debug) self.host = host self.portnumber = portnumber self.delay = delay self.client = Graphline( TCPCLIENT=TCPClient(self.host, self.portnumber, self.delay), PROTOCOL=self.jsonprotocol(), linkages={ ("TCPCLIENT", "outbox"): ("PROTOCOL", "inbox"), ("PROTOCOL", "outbox"): ("TCPCLIENT", "inbox"), ("TCPCLIENT", "signal"): ("PROTOCOL", "control"), ("PROTOCOL", "signal"): ("TCPCLIENT", "control"), }, ) self.handle = Handle(self.client) def start(self): if self.debug: print("Starting TCP Client - connecting to %s on port %s" % (self.host, self.portnumber)) ##self.client.run() try: background().start() except: pass # assume already running self.client.activate()
class JsonRpcTCPClient(JsonRPCBase): def __init__(self, host, portnumber, delay=0, workers=5, debug=1): JsonRPCBase.__init__(self, workers=workers, debug=debug) self.host = host self.portnumber = portnumber self.delay = delay self.client = Graphline( TCPCLIENT=TCPClient(self.host, self.portnumber, self.delay), PROTOCOL=self.jsonprotocol(), linkages={ ('TCPCLIENT', 'outbox'): ('PROTOCOL', 'inbox'), ('PROTOCOL', 'outbox'): ('TCPCLIENT', 'inbox'), ('TCPCLIENT', 'signal'): ('PROTOCOL', 'control'), ('PROTOCOL', 'signal'): ('TCPCLIENT', 'control'), }) self.handle = Handle(self.client) def start(self): if self.debug: print 'Starting TCP Client - connecting to %s on port %s' % ( self.host, self.portnumber) ##self.client.run() try: background().start() except: pass # assume already running self.client.activate()
def connectToLogger(component, logger_name): """ This method is used to connect a method with a log outbox to a logger. """ component.LoggerName = logger_name publisher = PublishTo('LOG_' + logger_name) graph = Graphline( COMPONENT = component, PUBLISHER = publisher, linkages = { ('COMPONENT', 'log') : ('PUBLISHER', 'inbox'), ('COMPONENT', 'signal') : ('PUBLISHER', 'control'), }) graph.activate() component.addChildren(publisher, graph)
def build_webui(): """ Constructs a WebUI consiting of WebGate with WebClients and a Router (PipeSelector) with the selector's components being defined by the build_urls() function. """ gate = Graphline(WG=WebGate(assetdir=os.path.abspath("/var/lib/hfos/static")), # LG=Logger(level=critical, name="WUI-IN"), ROUTER=PipeSelector(build_urls(), defaultpipe=build_404template), linkages={("WG", "outbox"): ("ROUTER", "inbox"), #("LG", "outbox"): ("ROUTER", "inbox"), ("ROUTER", "outbox"): ("WG", "inbox") } ) gate.activate()
def handlein(self): self.statement = self.recv() graphline = Graphline(get=GetCursor(service=self.service), begin=BeginTransaction(), exe=Execute(query=self.statement), end=self.end(), release=ReleaseCursor(service=self.service), linkages={ ('get', 'outbox'): ('begin', 'inbox'), ('begin', 'outbox'): ('exe', 'inbox'), ('exe', 'outbox'): ('end', 'inbox'), ('end', 'outbox'): ('release', 'inbox'), ('get', 'signal'): ('begin', 'control'), ('begin', 'signal'): ('exe', 'control'), ('exe', 'signal'): ('end', 'control'), ('end', 'signal'): ('release', 'control'), ('exe', 'response'): ('self', 'outbox'), ('release', 'signal'): ('self', 'signal'), }) self.link((graphline, "outbox"), (self, "outbox"), passthrough=2) if self.terminable: self.link((graphline, "signal"), (self, "signal"), passthrough=2) graphline.activate()
class Client(component): Inboxes = {"inbox" : "", "jid" : "", "streamfeat" : "", "control" : "Shutdown the client stream"} Outboxes = {"outbox" : "", "forward" : "", "log" : "", "doauth" : "", "signal" : "Shutdown signal", "doregistration" : ""} def __init__(self, username, password, domain, resource=u"headstock-client1", server=u'localhost', port=5222, usetls=False, register=False): super(Client, self).__init__() self.jid = JID(username, domain, resource) self.username = username self.password = password self.server = server self.port = port self.client = None self.graph = None self.domain = domain self.usetls = usetls self.register = register def passwordLookup(self, jid): return self.password def shutdown(self): self.send(Presence.to_element(Presence(self.jid, type=u'unavailable')), 'forward') self.send('OUTGOING : </stream:stream>', 'log') self.send('</stream:stream>', 'outbox') def abort(self): self.send('OUTGOING : </stream:stream>', 'log') self.send('</stream:stream>', 'outbox') def setup(self): # Backplanes are like a global entry points that # can be accessible both for publishing and # recieving data. # In other words, a component interested # in advertising to many other components that # something happened may link one of its outbox # to a PublishTo component's inbox. # A component wishing to receive that piece of # information will link one of its inbox # to the SubscribeTo component's outbox. # This helps greatly to make components more # loosely connected but also allows for some data # to be dispatched at once to many (such as when # the server returns the per-session JID that # is of interest for most other components). Backplane("CONSOLE").activate() Backplane("JID").activate() # Used to inform components that the session is now active Backplane("BOUND").activate() # Used to inform components of the supported features Backplane("DISCO_FEAT").activate() sub = SubscribeTo("JID") self.link((sub, 'outbox'), (self, 'jid')) self.addChildren(sub) sub.activate() # We pipe everything typed into the console # directly to the console backplane so that # every components subscribed to the console # backplane inbox will get the typed data and # will decide it it's of concern or not. Pipeline(ConsoleReader(), PublishTo('CONSOLE')).activate() # Add two outboxes ro the ClientSteam to support specific extensions. ClientStream.Outboxes["%s.query" % XMPP_IBR_NS] = "Registration" ClientStream.Outboxes["%s.query" % XMPP_LAST_NS] = "Activity" ClientStream.Outboxes["%s.query" % XMPP_DISCO_INFO_NS] = "Discovery" self.client = ClientStream(self.jid, self.passwordLookup, use_tls=self.usetls) self.graph = Graphline(client = self, console = SubscribeTo('CONSOLE'), logger = Logger(path=None, stdout=True), tcp = TCPClient(self.server, self.port), xmlparser = XMLIncrParser(), xmpp = self.client, streamerr = StreamError(), saslerr = SaslError(), discohandler = DiscoHandler(self.jid, self.domain), activityhandler = ActivityHandler(), rosterhandler = RosterHandler(self.jid), registerhandler = RegistrationHandler(self.username, self.password), msgdummyhandler = DummyMessageHandler(), presencehandler = PresenceHandler(), presencedisp = PresenceDispatcher(), rosterdisp = RosterDispatcher(), msgdisp = MessageDispatcher(), discodisp = DiscoveryDispatcher(), activitydisp = ActivityDispatcher(), registerdisp = RegisterDispatcher(), pjid = PublishTo("JID"), pbound = PublishTo("BOUND"), linkages = {('xmpp', 'terminated'): ('client', 'inbox'), ('console', 'outbox'): ('client', 'control'), ('client', 'forward'): ('xmpp', 'forward'), ('client', 'outbox'): ('tcp', 'inbox'), ('client', 'signal'): ('tcp', 'control'), ("tcp", "outbox") : ("xmlparser", "inbox"), ("xmpp", "starttls") : ("tcp", "makessl"), ("tcp", "sslready") : ("xmpp", "tlssuccess"), ("xmlparser", "outbox") : ("xmpp" , "inbox"), ("xmpp", "outbox") : ("tcp" , "inbox"), ("xmpp", "reset"): ("xmlparser", "reset"), ("client", "log"): ("logger", "inbox"), ("xmpp", "log"): ("logger", "inbox"), ("xmpp", "jid"): ("pjid", "inbox"), ("xmpp", "bound"): ("pbound", "inbox"), ("xmpp", "features"): ("client", "streamfeat"), ("client", "doauth"): ("xmpp", "auth"), # Registration ("xmpp", "%s.query" % XMPP_IBR_NS): ("registerdisp", "inbox"), ("registerdisp", "log"): ('logger', "inbox"), ("registerdisp", "xmpp.error"): ("registerhandler", "error"), ("registerdisp", "xmpp.result"): ("registerhandler", "inbox"), ("registerhandler", "outbox"): ("registerdisp", "forward"), ("client", "doregistration"): ("registerdisp", "forward"), ("registerdisp", "outbox"): ("xmpp", "forward"), # Presence ("xmpp", "%s.presence" % XMPP_CLIENT_NS): ("presencedisp", "inbox"), ("presencedisp", "log"): ('logger', "inbox"), ("presencedisp", "xmpp.subscribe"): ("presencehandler", "subscribe"), ("presencedisp", "xmpp.unsubscribe"): ("presencehandler", "unsubscribe"), ("presencehandler", "outbox"): ("presencedisp", "forward"), ("presencehandler", "roster"): ("rosterdisp", "forward"), ("presencedisp", "outbox"): ("xmpp", "forward"), # Roster ("xmpp", "%s.query" % XMPP_ROSTER_NS): ("rosterdisp", "inbox"), ("rosterdisp", "log"): ('logger', "inbox"), ('rosterdisp', 'xmpp.set'): ('rosterhandler', 'pushed'), ('rosterdisp', 'xmpp.result'): ('rosterhandler', 'inbox'), ('rosterhandler', 'result'): ('rosterdisp', 'forward'), ("rosterdisp", "outbox"): ("xmpp", "forward"), # Discovery ("xmpp", "%s.query" % XMPP_DISCO_INFO_NS): ("discodisp", "features.inbox"), ("discodisp", "log"): ('logger', "inbox"), ("discohandler", "features-disco"): ('discodisp', "features.forward"), ("discodisp", "out.features.result"): ('discohandler', "features.result"), ("discodisp", "outbox"): ("xmpp", "forward"), # Message ("xmpp", "%s.message" % XMPP_CLIENT_NS): ("msgdisp", "inbox"), ("msgdisp", "log"): ('logger', "inbox"), ("msgdisp", "xmpp.chat"): ('msgdummyhandler', 'inbox'), ("msgdummyhandler", "outbox"): ('msgdisp', 'forward'), ("msgdisp", "outbox"): ("xmpp", "forward"), # Activity ("xmpp", "%s.query" % XMPP_LAST_NS): ("activitydisp", "inbox"), ("activitydisp", "log"): ('logger', "inbox"), ("activitydisp", "outbox"): ("xmpp", "forward"), ("activityhandler", 'activity-supported'): ('rosterhandler', 'ask-activity'), ("rosterhandler", 'activity'): ('activitydisp', 'forward'), } ) self.addChildren(self.graph) self.graph.activate() return 1 def main(self): yield self.setup() while 1: if self.dataReady("control"): mes = self.recv("control") if isinstance(mes, str): if mes.strip() == 'quit': self.shutdown() elif isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): self.send(mes, "signal") break if self.dataReady("inbox"): msg = self.recv('inbox') if msg == "quit": self.send(shutdownMicroprocess(), "signal") yield 1 break if self.dataReady("streamfeat"): feat = self.recv('streamfeat') if feat.register and self.register: self.send(Registration(), 'doregistration') elif self.register and not feat.register: print "The server does not support in-band registration. Closing connection." self.abort() else: self.send(feat, 'doauth') if self.dataReady("jid"): self.jid = self.recv('jid') if not self.anyReady(): self.pause() yield 1 yield 1 self.stop() print "You can hit Ctrl-C to shutdown all processes now."
class Test_Graphline(unittest.TestCase): def setup_initialise(self, *listargs, **dictargs): self.children = {} for key in dictargs.keys(): if key != "linkages": self.children[key] = dictargs[key] self.scheduler = scheduler() scheduler.run = self.scheduler self.graphline = Graphline(*listargs, **dictargs) self.inSrc = {} for box in ["inbox", "control"]: c = Dummy() c.link((c, "outbox"), (self.graphline, box)) self.inSrc[box] = c self.outDest = {} for box in ["outbox", "signal"]: c = Dummy() c.link((self.graphline, box), (c, "inbox")) self.outDest[box] = c self.run = self.scheduler.main() def setup_activate(self): self.graphline.activate(Scheduler=self.scheduler) for c in self.inSrc.values(): c.activate(Scheduler=self.scheduler) for c in self.outDest.values(): c.activate(Scheduler=self.scheduler) def sendTo(self, data, boxname): self.ensureHandlerForInbox(boxname) self.inSrc[boxname].send(data, "outbox") def recvFrom(self, boxname): return self.outDest[boxname].recv("inbox") def dataReadyAt(self, boxname): return self.outDest[boxname].dataReady("inbox") def ensureHandlerForInbox(self, boxname): if not boxname in self.inSrc: try: c = Dummy() c.link((c, "outbox"), (self.graphline, boxname)) c.activate(Scheduler=self.scheduler) self.inSrc[boxname] = c except KeyError: self.fail("Expected inbox '" + boxname + "' on graphline does not exist") def ensureHandlerForOutbox(self, boxname): if not boxname in self.outDest: try: c = Dummy() c.link((self.graphline, boxname), (c, "inbox")) c.activate(Scheduler=self.scheduler) self.outDest[boxname] = c except KeyError: self.fail("Expected inbox '" + boxname + "' on graphline does not exist") def runFor(self, cycles): numcycles = cycles * (len(self.inSrc) + len(self.outDest) + 1 + len( self.children)) # approx this many components in the system for i in range(0, numcycles): self.run.next() def checkDataFlows(self, source, *targets): (fromComponent, fromBox) = source DATA = object() for (toComponent, toBox) in targets: if toComponent == self.graphline: self.ensureHandlerForOutbox(toBox) if fromComponent == self.graphline: self.sendTo(DATA, fromBox) else: fromComponent.send(DATA, fromBox) self.runFor(cycles=1) for (toComponent, toBox) in targets: if toComponent == self.graphline: self.assert_(self.dataReadyAt(toBox)) self.assertEquals(DATA, self.recvFrom(toBox)) else: self.assert_(toComponent.dataReady(toBox)) self.assertEquals(DATA, toComponent.recv(toBox)) for child in self.children.values(): if child not in [toComponent for (toComponent, toBox) in targets]: self.assert_(not (child.anyReady())) def test_smokeTest(self): """Instantiating a graphline with no arguments results in a ValueError exception""" self.failUnlessRaises(ValueError, Graphline) def test_graphlineNoLinkagesArg(self): """Instantiating with components as named arguments, but specifying no linkages argument results in a ValueError exception""" self.failUnlessRaises(ValueError, Graphline, A=component(), B=component()) def test_graphlineEmptyLinkagesArg(self): """Instantiating with components as named arguments, and specifying an empty linkages argument succeeds""" Graphline(A=component(), B=component(), linkages={}) def test_graphlineNoComponentsEmptyLinkagesArg(self): """Instantiating with no components as named arguments, and specifying an empty linkages argument succeeds""" Graphline(linkages={}) def test_graphlineHasChildren(self): """Instantiating a graphline, components specified as named arguments, eg. A=component() and B=component() become children of the graphline once activated and run.""" self.setup_initialise(A=component(), B=component(), linkages={}) self.setup_activate() self.runFor(cycles=1) gChildren = self.graphline.childComponents() for c in self.children.values(): self.assert_(c in gChildren) def test_unactivatedGraphlineHasNoChildren(self): """Instantiating a graphline, components specified as named arguments, eg. A=component() and B=component() will not be children of the graphline before it is activated and run""" self.setup_initialise(A=component(), B=component(), linkages={}) gChildren = self.graphline.childComponents() for c in self.children.values(): self.assert_(not (c in gChildren)) def test_activatesChildrenOnlyWhenActivatedNotLinked(self): """Children are activated as soon as the Graphline itself is activated, but no sooner. They get activated even if they have no linkages specified to them.""" self.setup_initialise(A=MockChild(), B=MockChild(), C=MockChild(), linkages={}) for child in self.children.values(): self.assert_(not (child.wasActivated)) self.setup_activate() self.runFor(cycles=1) self.runFor(cycles=3) for child in self.children.values(): self.assert_(child.wasActivated) def test_activatesChildrenOnlyWhenActivatedLinked(self): """Children are activated as soon as the Graphline itself is activated, but no sooner. They get activated even if they have no linkages specified to them.""" self.setup_initialise(A=MockChild(), B=MockChild(), C=MockChild(), linkages={ ("A", "outbox"): ("B", "inbox"), ("B", "outbox"): ("C", "inbox"), ("C", "outbox"): ("A", "inbox"), }) for child in self.children.values(): self.assert_(not (child.wasActivated)) self.setup_activate() self.runFor(cycles=1) self.runFor(cycles=3) for child in self.children.values(): self.assert_(child.wasActivated) def test_linkagesBetweenComponents(self): """A linkage from "outbox" to "inbox" between two named child components "A" and "B" can be specified by specifying a "linkages" argument containing a dictionary with an entry: ("A","outbox"):("B","inbox"). Data sent to A's "outbox" will reach B's "inbox" and nowhere else.""" A = MockChild() B = MockChild() self.setup_initialise(A=A, B=B, linkages={("A", "outbox"): ("B", "inbox")}) self.setup_activate() self.runFor(cycles=1) self.checkDataFlows((A, "outbox"), (B, "inbox")) def test_severalLinkagesBetweenComponents(self): """Several linkages can be specified between components. They will all be created, and messages will be able to flow along them once the graphline is activated and run. Data will only flow along the specified linkages and will not leak anywhere else!""" A = MockChild() B = MockChild() C = MockChild() D = MockChild() self.setup_initialise(A=A, B=B, C=C, D=D, linkages={ ("A", "outbox"): ("B", "inbox"), ("C", "outbox"): ("D", "control"), ("C", "signal"): ("A", "inbox"), ("B", "signal"): ("A", "control"), }) self.setup_activate() self.runFor(cycles=1) self.checkDataFlows((A, "outbox"), (B, "inbox")) self.checkDataFlows((C, "outbox"), (D, "control")) self.checkDataFlows((C, "signal"), (A, "inbox")) self.checkDataFlows((B, "signal"), (A, "control")) def test_terminateWhenAllChildrenHaveTerminated(self): """Graphline will terminate when all of its children have terminated, but not before.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): ("B", "inbox"), }) self.setup_activate() for i in range(0, 2): self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=2) self.assert_(not (self.graphline in self.scheduler.listAllThreads())) def test_specifyingPassthruInLinkage(self): """If a linkage is specified whose source is (X, "inbox") or (X, "control") where X is not the name given to one of the child components in the graphline, then the linkage created is a passthrough from that named inbox of the graphline to the specified destination child component in the graphline.""" selectionOfUnusedNames = [ "", "self", "flurble", "a", "component", "pig" ] for name in selectionOfUnusedNames: A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ (name, "inbox"): ("A", "control"), (name, "control"): ("B", "inbox"), ("C", "outbox"): ("A", "inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((self.graphline, "inbox"), (A, "control")) self.checkDataFlows((self.graphline, "control"), (B, "inbox")) def test_specifyingPassthruInLinkageNewBox(self): """If a linkage is specified whose source is (X, Y) where X is not the name given to one of the child components in the graphline and Y is neither "inbox" nor "control", then an inbox with name Y is created and the linkage created is a passthrough from that named inbox of the graphline to the specified destination child component in the graphline.""" selectionOfUnusedNames = [ "", "self", "flurble", "a", "component", "pig" ] for name in selectionOfUnusedNames: A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ (name, "novel-inbox"): ("A", "control"), (name, "another-novel-inbox"): ("B", "inbox"), ("C", "outbox"): ("A", "inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((self.graphline, "novel-inbox"), (A, "control")) self.checkDataFlows((self.graphline, "another-novel-inbox"), (B, "inbox")) def test_specifyingPassthruOutLinkage(self): """If a linkage is specified whose destination is (X, "outbox") or (X, "signal") where X is not the name given to one of the child components in the graphline, then the linkage created is a passthrough from the specified source child component in the graphline to that named outbox of the graphline.""" selectionOfUnusedNames = [ "", "self", "flurble", "a", "component", "pig" ] for name in selectionOfUnusedNames: A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): (name, "signal"), ("B", "signal"): (name, "outbox"), ("C", "outbox"): ("A", "inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((A, "outbox"), (self.graphline, "signal")) self.checkDataFlows((B, "signal"), (self.graphline, "outbox")) def test_specifyingPassthruOutLinkageNewBox(self): """If a linkage is specified whose destination is (X, Y) where X is not the name given to one of the child components in the graphline and Y is neither "outbox" nor "signal", then an outbox with name Y is created and the linkage created is a passthrough from the specified source child component in the graphline to that named outbox of the graphline.""" selectionOfUnusedNames = [ "", "self", "flurble", "a", "component", "pig" ] for name in selectionOfUnusedNames: A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): (name, "novel-boxname"), ("B", "signal"): (name, "another-novel-boxname"), ("C", "outbox"): ("A", "inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((A, "outbox"), (self.graphline, "novel-boxname")) self.checkDataFlows((B, "signal"), (self.graphline, "another-novel-boxname")) def test_emissionOfShutdownSignal_1(self): """When all children have terminated. If no child is wired to the Graphline's "signal" outbox, the Graphline will send out its own message. The message sent will be a producerFinished message if a child is wired to the Graphline's "control" inbox, or if no shutdownMicroprocess message has been previously received on that inbox.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): ("B", "inbox"), }) self.setup_activate() self.runFor(cycles=100) # check nothing has been emitted yet! self.assert_(not (self.dataReadyAt("signal"))) for child in self.children.values(): child.stopNow() self.runFor(cycles=2) self.assert_(self.dataReadyAt("signal")) self.assert_(isinstance(self.recvFrom("signal"), producerFinished)) ## FIXME: This test is definitely broken since an example ## Doing this exists in Examples, and works :-) def test_emissionOfShutdownSignal_2(self): """When all children have terminated. If no child is wired to the Graphline's "signal" outbox, the Graphline will send out its own message. If no child is wired to the Graphline's "control" inbox and a shutdownMicroprocess message has been previously received on that inbox, then the message sent out will be that shutdownMicroprocess message.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): ("B", "inbox"), }) self.setup_activate() self.runFor(cycles=100) # check nothing has been emitted yet! self.assert_(not (self.dataReadyAt("signal"))) shutdownMsg = shutdownMicroprocess() self.sendTo(shutdownMsg, "control") self.runFor(cycles=1) for child in self.children.values(): child.stopNow() self.runFor(cycles=3) self.assert_(self.dataReadyAt("signal")) recvd = self.recvFrom("signal") self.assert_(recvd == shutdownMsg) def test_receivesShutdownPassesThru(self): """If a graphline's "control" inbox is specified to be wired to a child component in the graphline, then any message (including shutdown messages) flow along that linkage only.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("", "control"): ("A", "control"), }) self.setup_activate() self.runFor(cycles=100) self.checkDataFlows((self.graphline, "control"), (A, "control")) ## FIXME: This test is definitely broken since an example ## Doing this exists in Examples, and works :-) def test_receivesShutdownDisseminated(self): """If a graphline's "control" inbox is not specified to be wired to a child component in the graphline, then any message (including shutdown messages) flows to the "control" inbox of all children without linkages going to their "control" inbox only.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A", "outbox"): ("B", "control"), # should block msg getting to B }) self.setup_activate() self.runFor(cycles=100) msg = shutdownMicroprocess() self.sendTo(msg, "control") self.runFor(cycles=2) self.assert_(A.dataReady("control")) self.assertEquals(msg, A.recv("control")) self.assert_(not (B.dataReady("control"))) self.assert_(C.dataReady("control")) self.assertEquals(msg, C.recv("control")) def test_receivesShutdownAndPropagates(self): """If a graphline's "control" inbox and "signal" outbox are not specified to be wired to a child component in the graphline then, if a shutdownMicroprocess message is sent to the "control" inbox, it will be sent on out of the "signal" outbox once all children have terminated.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): ("B", "control"), }) self.setup_activate() self.runFor(cycles=100) msg = shutdownMicroprocess() self.sendTo(msg, "control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=10) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(self.dataReadyAt("signal")) self.assertEquals(msg, self.recvFrom("signal")) def test_receivesShutdownAndPropagates2(self): """If a graphline's "control" inbox and "signal" outbox are not specified to be wired to a child component in the graphline then, if a any non shutdownMicroprocess message is sent to the "control" inbox, a producerFinished message will be sent on out of the "signal" outbox once all children have terminated.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "outbox"): ("B", "control"), }) self.setup_activate() self.runFor(cycles=100) msg = producerFinished() self.sendTo(msg, "control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=10) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(self.dataReadyAt("signal")) recvd = self.recvFrom("signal") self.assert_(recvd != msg) self.assert_(isinstance(recvd, producerFinished)) def test_receivesShutdownAndPropagates23(self): """If a graphline's "control" inbox is specified to be wired to a child component, but its "signal" outbox is not then, irrespective of what message (eg. shutdownMicroprocess) is sent to the "control" inbox, a producerFinished message will be sent on out of the "signal" outbox once all children have terminated.""" possibleMessages = [ producerFinished(), shutdownMicroprocess(), "flurble" ] for msg in possibleMessages: A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("", "control"): ("A", "control"), ("A", "outbox"): ("B", "control"), }) self.setup_activate() self.runFor(cycles=100) self.sendTo(msg, "control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=10) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(self.dataReadyAt("signal")) recvd = self.recvFrom("signal") self.assert_(recvd != msg) self.assert_(isinstance(recvd, producerFinished)) def test_doesNotPropagateShutdownMsg(self): """If a graphline's "signal" outbox is specified to be wired to a child component, the graphline will send any messages itself out of its "signal" outbox, before or after all children have terminated, even if a shutdownMicroprocess or producerFinished message was sent to its "control" inbox.""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A", "signal"): ("", "signal"), ("A", "outbox"): ("B", "control"), }) self.setup_activate() self.runFor(cycles=100) self.sendTo(producerFinished(), "control") self.sendTo(shutdownMicroprocess(), "control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) self.assert_(not (self.dataReadyAt("signal"))) for child in self.children.values(): child.stopNow() self.runFor(cycles=100) self.assert_(not (self.dataReadyAt("signal"))) def test_manuallyImplementedShutdownOverrides(self): """If a graphline's "control" inbox and "signal" outbox are both specified to be wired to child components in the graphline, then graphline will not emit its own messages out of its "signal" outbox when it terminates (or at any other time)""" A = MockChild() B = MockChild() C = MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("", "control"): ("A", "control"), ("A", "signal"): ("", "signal"), ("B", "outbox"): ("C", "inbox"), }) self.setup_activate() self.runFor(cycles=100) self.assert_(not (self.dataReadyAt("outbox"))) self.assert_(not (self.dataReadyAt("signal"))) self.checkDataFlows((self.graphline, "control"), (A, "control")) self.checkDataFlows((A, "signal"), (self.graphline, "signal")) self.checkDataFlows((B, "outbox"), (C, "inbox")) self.runFor(cycles=100) self.assert_(not (self.dataReadyAt("outbox"))) self.assert_(not (self.dataReadyAt("signal"))) for child in self.children.values(): child.stopNow() self.runFor(cycles=100) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(not (self.dataReadyAt("outbox"))) self.assert_(not (self.dataReadyAt("signal"))) # hack to make this work in python 2.3 # where assertTrue and assertFalse are not defined try: unittest.TestCase.assertTrue except AttributeError: def assertTrue(self, X): return self.assert_(X) try: unittest.TestCase.assertFalse except AttributeError: def assertFalse(self, X): return self.assert_(not X)
class Test_Graphline(unittest.TestCase): def setup_initialise(self,*listargs,**dictargs): self.children = {} for key in dictargs.keys(): if key != "linkages": self.children[key] = dictargs[key] self.scheduler = scheduler() scheduler.run = self.scheduler self.graphline = Graphline(*listargs, **dictargs) self.inSrc = {} for box in ["inbox","control"]: c = Dummy() c.link((c,"outbox"), (self.graphline,box)) self.inSrc[box]=c self.outDest = {} for box in ["outbox","signal"]: c = Dummy() c.link((self.graphline,box), (c,"inbox")) self.outDest[box]=c self.run = self.scheduler.main() def setup_activate(self): self.graphline.activate(Scheduler=self.scheduler) for c in self.inSrc.values(): c.activate(Scheduler=self.scheduler) for c in self.outDest.values(): c.activate(Scheduler=self.scheduler) def sendTo(self,data,boxname): self.ensureHandlerForInbox(boxname) self.inSrc[boxname].send(data,"outbox") def recvFrom(self,boxname): return self.outDest[boxname].recv("inbox") def dataReadyAt(self,boxname): return self.outDest[boxname].dataReady("inbox") def ensureHandlerForInbox(self,boxname): if not boxname in self.inSrc: try: c=Dummy() c.link((c,"outbox"), (self.graphline,boxname)) c.activate(Scheduler=self.scheduler) self.inSrc[boxname]=c except KeyError: self.fail("Expected inbox '"+boxname+"' on graphline does not exist") def ensureHandlerForOutbox(self,boxname): if not boxname in self.outDest: try: c=Dummy() c.link((self.graphline,boxname), (c,"inbox")) c.activate(Scheduler=self.scheduler) self.outDest[boxname]=c except KeyError: self.fail("Expected inbox '"+boxname+"' on graphline does not exist") def runFor(self, cycles): numcycles=cycles*(len(self.inSrc)+len(self.outDest)+1+len(self.children)) # approx this many components in the system for i in range(0,numcycles): self.run.next() def checkDataFlows(self, source, *targets): (fromComponent, fromBox) = source DATA=object() for (toComponent,toBox) in targets: if toComponent==self.graphline: self.ensureHandlerForOutbox(toBox) if fromComponent==self.graphline: self.sendTo(DATA,fromBox) else: fromComponent.send(DATA,fromBox) self.runFor(cycles=1) for (toComponent,toBox) in targets: if toComponent==self.graphline: self.assert_(self.dataReadyAt(toBox)) self.assertEquals(DATA, self.recvFrom(toBox)) else: self.assert_(toComponent.dataReady(toBox)) self.assertEquals(DATA, toComponent.recv(toBox)) for child in self.children.values(): if child not in [toComponent for (toComponent,toBox) in targets]: self.assert_(not(child.anyReady())) def test_smokeTest(self): """Instantiating a graphline with no arguments results in a ValueError exception""" self.failUnlessRaises(ValueError, Graphline) def test_graphlineNoLinkagesArg(self): """Instantiating with components as named arguments, but specifying no linkages argument results in a ValueError exception""" self.failUnlessRaises(ValueError, Graphline, A=component(), B=component()) def test_graphlineEmptyLinkagesArg(self): """Instantiating with components as named arguments, and specifying an empty linkages argument succeeds""" Graphline(A=component(), B=component(), linkages={}) def test_graphlineNoComponentsEmptyLinkagesArg(self): """Instantiating with no components as named arguments, and specifying an empty linkages argument succeeds""" Graphline(linkages={}) def test_graphlineHasChildren(self): """Instantiating a graphline, components specified as named arguments, eg. A=component() and B=component() become children of the graphline once activated and run.""" self.setup_initialise(A=component(), B=component(), linkages={}) self.setup_activate() self.runFor(cycles=1) gChildren = self.graphline.childComponents() for c in self.children.values(): self.assert_(c in gChildren) def test_unactivatedGraphlineHasNoChildren(self): """Instantiating a graphline, components specified as named arguments, eg. A=component() and B=component() will not be children of the graphline before it is activated and run""" self.setup_initialise(A=component(), B=component(), linkages={}) gChildren = self.graphline.childComponents() for c in self.children.values(): self.assert_(not(c in gChildren)) def test_activatesChildrenOnlyWhenActivatedNotLinked(self): """Children are activated as soon as the Graphline itself is activated, but no sooner. They get activated even if they have no linkages specified to them.""" self.setup_initialise(A=MockChild(), B=MockChild(), C=MockChild(), linkages={}) for child in self.children.values(): self.assert_(not(child.wasActivated)) self.setup_activate() self.runFor(cycles=1) self.runFor(cycles=3) for child in self.children.values(): self.assert_(child.wasActivated) def test_activatesChildrenOnlyWhenActivatedLinked(self): """Children are activated as soon as the Graphline itself is activated, but no sooner. They get activated even if they have no linkages specified to them.""" self.setup_initialise(A=MockChild(), B=MockChild(), C=MockChild(), linkages={ ("A","outbox"):("B","inbox"), ("B","outbox"):("C","inbox"), ("C","outbox"):("A","inbox"), }) for child in self.children.values(): self.assert_(not(child.wasActivated)) self.setup_activate() self.runFor(cycles=1) self.runFor(cycles=3) for child in self.children.values(): self.assert_(child.wasActivated) def test_linkagesBetweenComponents(self): """A linkage from "outbox" to "inbox" between two named child components "A" and "B" can be specified by specifying a "linkages" argument containing a dictionary with an entry: ("A","outbox"):("B","inbox"). Data sent to A's "outbox" will reach B's "inbox" and nowhere else.""" A=MockChild() B=MockChild() self.setup_initialise(A=A, B=B, linkages={("A","outbox"):("B","inbox")}) self.setup_activate() self.runFor(cycles=1) self.checkDataFlows((A,"outbox"),(B,"inbox")) def test_severalLinkagesBetweenComponents(self): """Several linkages can be specified between components. They will all be created, and messages will be able to flow along them once the graphline is activated and run. Data will only flow along the specified linkages and will not leak anywhere else!""" A=MockChild() B=MockChild() C=MockChild() D=MockChild() self.setup_initialise( A=A, B=B, C=C, D=D, linkages={ ("A","outbox"):("B","inbox"), ("C","outbox"):("D","control"), ("C","signal"):("A","inbox"), ("B","signal"):("A","control"), } ) self.setup_activate() self.runFor(cycles=1) self.checkDataFlows((A,"outbox"),(B,"inbox")) self.checkDataFlows((C,"outbox"),(D,"control")) self.checkDataFlows((C,"signal"),(A,"inbox")) self.checkDataFlows((B,"signal"),(A,"control")) def test_terminateWhenAllChildrenHaveTerminated(self): """Graphline will terminate when all of its children have terminated, but not before.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A","outbox"):("B","inbox"), } ) self.setup_activate() for i in range(0,2): self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=2) self.assert_(not(self.graphline in self.scheduler.listAllThreads())) def test_specifyingPassthruInLinkage(self): """If a linkage is specified whose source is (X, "inbox") or (X, "control") where X is not the name given to one of the child components in the graphline, then the linkage created is a passthrough from that named inbox of the graphline to the specified destination child component in the graphline.""" selectionOfUnusedNames = ["", "self", "flurble", "a", "component", "pig"] for name in selectionOfUnusedNames: A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ (name,"inbox"):("A","control"), (name,"control"):("B","inbox"), ("C","outbox"):("A","inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((self.graphline,"inbox"),(A,"control")) self.checkDataFlows((self.graphline,"control"),(B,"inbox")) def test_specifyingPassthruInLinkageNewBox(self): """If a linkage is specified whose source is (X, Y) where X is not the name given to one of the child components in the graphline and Y is neither "inbox" nor "control", then an inbox with name Y is created and the linkage created is a passthrough from that named inbox of the graphline to the specified destination child component in the graphline.""" selectionOfUnusedNames = ["", "self", "flurble", "a", "component", "pig"] for name in selectionOfUnusedNames: A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ (name,"novel-inbox"):("A","control"), (name,"another-novel-inbox"):("B","inbox"), ("C","outbox"):("A","inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((self.graphline,"novel-inbox"),(A,"control")) self.checkDataFlows((self.graphline,"another-novel-inbox"),(B,"inbox")) def test_specifyingPassthruOutLinkage(self): """If a linkage is specified whose destination is (X, "outbox") or (X, "signal") where X is not the name given to one of the child components in the graphline, then the linkage created is a passthrough from the specified source child component in the graphline to that named outbox of the graphline.""" selectionOfUnusedNames = ["", "self", "flurble", "a", "component", "pig"] for name in selectionOfUnusedNames: A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A","outbox"):(name,"signal"), ("B","signal"):(name,"outbox"), ("C","outbox"):("A","inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((A,"outbox"),(self.graphline,"signal")) self.checkDataFlows((B,"signal"),(self.graphline,"outbox")) def test_specifyingPassthruOutLinkageNewBox(self): """If a linkage is specified whose destination is (X, Y) where X is not the name given to one of the child components in the graphline and Y is neither "outbox" nor "signal", then an outbox with name Y is created and the linkage created is a passthrough from the specified source child component in the graphline to that named outbox of the graphline.""" selectionOfUnusedNames = ["", "self", "flurble", "a", "component", "pig"] for name in selectionOfUnusedNames: A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A","outbox"):(name,"novel-boxname"), ("B","signal"):(name,"another-novel-boxname"), ("C","outbox"):("A","inbox"), }) self.setup_activate() self.runFor(cycles=10) self.checkDataFlows((A,"outbox"),(self.graphline,"novel-boxname")) self.checkDataFlows((B,"signal"),(self.graphline,"another-novel-boxname")) def test_emissionOfShutdownSignal_1(self): """When all children have terminated. If no child is wired to the Graphline's "signal" outbox, the Graphline will send out its own message. The message sent will be a producerFinished message if a child is wired to the Graphline's "control" inbox, or if no shutdownMicroprocess message has been previously received on that inbox.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A","outbox"):("B","inbox"), } ) self.setup_activate() self.runFor(cycles=100) # check nothing has been emitted yet! self.assert_(not(self.dataReadyAt("signal"))) for child in self.children.values(): child.stopNow() self.runFor(cycles=2) self.assert_(self.dataReadyAt("signal")) self.assert_(isinstance(self.recvFrom("signal"), producerFinished)) ## FIXME: This test is definitely broken since an example ## Doing this exists in Examples, and works :-) def test_emissionOfShutdownSignal_2(self): """When all children have terminated. If no child is wired to the Graphline's "signal" outbox, the Graphline will send out its own message. If no child is wired to the Graphline's "control" inbox and a shutdownMicroprocess message has been previously received on that inbox, then the message sent out will be that shutdownMicroprocess message.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("A","outbox"):("B","inbox"), } ) self.setup_activate() self.runFor(cycles=100) # check nothing has been emitted yet! self.assert_(not(self.dataReadyAt("signal"))) shutdownMsg = shutdownMicroprocess(); self.sendTo(shutdownMsg,"control") self.runFor(cycles=1) for child in self.children.values(): child.stopNow() self.runFor(cycles=3) self.assert_(self.dataReadyAt("signal")) recvd=self.recvFrom("signal") self.assert_(recvd == shutdownMsg) def test_receivesShutdownPassesThru(self): """If a graphline's "control" inbox is specified to be wired to a child component in the graphline, then any message (including shutdown messages) flow along that linkage only.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise(A=A, B=B, C=C, linkages={ ("","control"):("A","control"), } ) self.setup_activate() self.runFor(cycles=100) self.checkDataFlows((self.graphline,"control"),(A,"control")) ## FIXME: This test is definitely broken since an example ## Doing this exists in Examples, and works :-) def test_receivesShutdownDisseminated(self): """If a graphline's "control" inbox is not specified to be wired to a child component in the graphline, then any message (including shutdown messages) flows to the "control" inbox of all children without linkages going to their "control" inbox only.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A","outbox"):("B","control"), # should block msg getting to B }) self.setup_activate() self.runFor(cycles=100) msg=shutdownMicroprocess() self.sendTo(msg,"control") self.runFor(cycles=2) self.assert_(A.dataReady("control")) self.assertEquals(msg, A.recv("control")) self.assert_(not(B.dataReady("control"))) self.assert_(C.dataReady("control")) self.assertEquals(msg, C.recv("control")) def test_receivesShutdownAndPropagates(self): """If a graphline's "control" inbox and "signal" outbox are not specified to be wired to a child component in the graphline then, if a shutdownMicroprocess message is sent to the "control" inbox, it will be sent on out of the "signal" outbox once all children have terminated.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A","outbox"):("B","control"), }) self.setup_activate() self.runFor(cycles=100) msg=shutdownMicroprocess() self.sendTo(msg,"control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=10) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(self.dataReadyAt("signal")) self.assertEquals(msg, self.recvFrom("signal")) def test_receivesShutdownAndPropagates2(self): """If a graphline's "control" inbox and "signal" outbox are not specified to be wired to a child component in the graphline then, if a any non shutdownMicroprocess message is sent to the "control" inbox, a producerFinished message will be sent on out of the "signal" outbox once all children have terminated.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A","outbox"):("B","control"), }) self.setup_activate() self.runFor(cycles=100) msg=producerFinished() self.sendTo(msg,"control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=10) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(self.dataReadyAt("signal")) recvd=self.recvFrom("signal") self.assert_(recvd != msg) self.assert_(isinstance(recvd,producerFinished)) def test_receivesShutdownAndPropagates23(self): """If a graphline's "control" inbox is specified to be wired to a child component, but its "signal" outbox is not then, irrespective of what message (eg. shutdownMicroprocess) is sent to the "control" inbox, a producerFinished message will be sent on out of the "signal" outbox once all children have terminated.""" possibleMessages = [ producerFinished(), shutdownMicroprocess(), "flurble" ] for msg in possibleMessages: A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("","control"):("A","control"), ("A","outbox"):("B","control"), }) self.setup_activate() self.runFor(cycles=100) self.sendTo(msg,"control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) for child in self.children.values(): child.stopNow() self.runFor(cycles=10) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(self.dataReadyAt("signal")) recvd=self.recvFrom("signal") self.assert_(recvd != msg) self.assert_(isinstance(recvd,producerFinished)) def test_doesNotPropagateShutdownMsg(self): """If a graphline's "signal" outbox is specified to be wired to a child component, the graphline will send any messages itself out of its "signal" outbox, before or after all children have terminated, even if a shutdownMicroprocess or producerFinished message was sent to its "control" inbox.""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("A","signal"):("","signal"), ("A","outbox"):("B","control"), }) self.setup_activate() self.runFor(cycles=100) self.sendTo(producerFinished(), "control") self.sendTo(shutdownMicroprocess(), "control") self.runFor(cycles=100) self.assert_(self.graphline in self.scheduler.listAllThreads()) self.assert_(not(self.dataReadyAt("signal"))) for child in self.children.values(): child.stopNow() self.runFor(cycles=100) self.assert_(not(self.dataReadyAt("signal"))) def test_manuallyImplementedShutdownOverrides(self): """If a graphline's "control" inbox and "signal" outbox are both specified to be wired to child components in the graphline, then graphline will not emit its own messages out of its "signal" outbox when it terminates (or at any other time)""" A=MockChild() B=MockChild() C=MockChild() self.setup_initialise( A=A, B=B, C=C, linkages={ ("","control"):("A","control"), ("A","signal"):("","signal"), ("B","outbox"):("C","inbox"), }) self.setup_activate() self.runFor(cycles=100) self.assert_(not(self.dataReadyAt("outbox"))) self.assert_(not(self.dataReadyAt("signal"))) self.checkDataFlows((self.graphline,"control"),(A,"control")) self.checkDataFlows((A,"signal"),(self.graphline,"signal")) self.checkDataFlows((B,"outbox"),(C,"inbox")) self.runFor(cycles=100) self.assert_(not(self.dataReadyAt("outbox"))) self.assert_(not(self.dataReadyAt("signal"))) for child in self.children.values(): child.stopNow() self.runFor(cycles=100) self.assert_(self.graphline not in self.scheduler.listAllThreads()) self.assert_(not(self.dataReadyAt("outbox"))) self.assert_(not(self.dataReadyAt("signal"))) # hack to make this work in python 2.3 # where assertTrue and assertFalse are not defined try: unittest.TestCase.assertTrue except AttributeError: def assertTrue(self,X): return self.assert_(X) try: unittest.TestCase.assertFalse except AttributeError: def assertFalse(self,X): return self.assert_(not X)
class Client(component): Inboxes = {"inbox" : "", "jid" : "", "streamfeat" : "", "control" : "Shutdown the client stream", "http-inbox" : "Receive messages to an HTTP Server",} Outboxes = {"outbox" : "", "forward" : "", "log" : "", "doauth" : "", "signal" : "Shutdown signal", "lw-signal" : "Shutdown signal for WsgiLogWritable", "doregistration" : ""} def __init__(self, username, password, domain, resource=u"headstock-client1", server=u'localhost', port=5222, usetls=False, register=False, log='/home/jason/chat.log'): super(Client, self).__init__() self.jid = JID(username, domain, resource) self.username = username self.password = password self.server = server self.port = port self.client = None self.graph = None self.domain = domain self.usetls = usetls self.register = register self.log_location = log def passwordLookup(self, jid): return self.password def shutdown(self): self.send(Presence.to_element(Presence(self.jid, type=u'unavailable')), 'forward') self.send('OUTGOING : </stream:stream>', 'log') self.send('</stream:stream>', 'outbox') def abort(self): self.send('OUTGOING : </stream:stream>', 'log') self.send('</stream:stream>', 'outbox') def setup(self): # Backplanes are like a global entry points that # can be accessible both for publishing and # recieving data. # In other words, a component interested # in advertising to many other components that # something happened may link one of its outbox # to a PublishTo component's inbox. # A component wishing to receive that piece of # information will link one of its inbox # to the SubscribeTo component's outbox. # This helps greatly to make components more # loosely connected but also allows for some data # to be dispatched at once to many (such as when # the server returns the per-session JID that # is of interest for most other components). Backplane("CONSOLE").activate() Backplane("JID").activate() # Used to inform components that the session is now active Backplane("BOUND").activate() # Used to inform components of the supported features Backplane("DISCO_FEAT").activate() sub = SubscribeTo("JID") self.link((sub, 'outbox'), (self, 'jid')) self.addChildren(sub) sub.activate() log = Logger(path=None, stdout=True, name='XmppLogger') Backplane('LOG_' + self.log_location).activate() Pipeline(SubscribeTo('LOG_' + self.log_location), log).activate() log_writable = WsgiLogWritable(self.log_location) log.activate() log_writable.activate() # We pipe everything typed into the console # directly to the console backplane so that # every components subscribed to the console # backplane inbox will get the typed data and # will decide it it's of concern or not. Pipeline(ConsoleReader(), PublishTo('CONSOLE')).activate() # Add two outboxes ro the ClientSteam to support specific extensions. ClientStream.Outboxes["%s.query" % XMPP_IBR_NS] = "Registration" ClientStream.Outboxes["%s.query" % XMPP_LAST_NS] = "Activity" ClientStream.Outboxes["%s.query" % XMPP_DISCO_INFO_NS] = "Discovery" self.client = ClientStream(self.jid, self.passwordLookup, use_tls=self.usetls) WsgiConfig ={ 'server_software' : "Example WSGI Web Server", 'server_admin' : "Jason Baker", 'wsgi_ver' : (1,0), } routing = [ ["/", SimpleWsgiFactory(log_writable, WsgiConfig, simple_app, '/simple')], ] #routing = [ ['/', Echoer]] self.graph = Graphline(client = self, console = SubscribeTo('CONSOLE'), logger = PublishTo('LOG_' + self.log_location), tcp = TCPClient(self.server, self.port), xmlparser = XMLIncrParser(), xmpp = self.client, streamerr = StreamError(), saslerr = SaslError(), discohandler = DiscoHandler(self.jid, self.domain), activityhandler = ActivityHandler(), rosterhandler = RosterHandler(self.jid), registerhandler = RegistrationHandler(self.username, self.password), msgdummyhandler = WebMessageHandler(), presencehandler = PresenceHandler(), presencedisp = PresenceDispatcher(), rosterdisp = RosterDispatcher(), msgdisp = MessageDispatcher(), discodisp = DiscoveryDispatcher(), activitydisp = ActivityDispatcher(), registerdisp = RegisterDispatcher(), pjid = PublishTo("JID"), pbound = PublishTo("BOUND"), proto_man = ProtocolManager(Protocol=HTTPProtocol(routing)), linkages = {('xmpp', 'terminated'): ('client', 'inbox'), ('console', 'outbox'): ('client', 'control'), ('client', 'forward'): ('xmpp', 'forward'), ('client', 'outbox'): ('tcp', 'inbox'), ('client', 'signal'): ('tcp', 'control'), ("tcp", "outbox") : ("xmlparser", "inbox"), ("xmpp", "starttls") : ("tcp", "makessl"), ("tcp", "sslready") : ("xmpp", "tlssuccess"), ("xmlparser", "outbox") : ("xmpp" , "inbox"), ("xmpp", "outbox") : ("tcp" , "inbox"), ("xmpp", "reset"): ("xmlparser", "reset"), ("client", "log"): ("logger", "inbox"), ("xmpp", "log"): ("logger", "inbox"), ("xmpp", "jid"): ("pjid", "inbox"), ("xmpp", "bound"): ("pbound", "inbox"), ("xmpp", "features"): ("client", "streamfeat"), ("client", "doauth"): ("xmpp", "auth"), # Registration ("xmpp", "%s.query" % XMPP_IBR_NS): ("registerdisp", "inbox"), ("registerdisp", "log"): ('logger', "inbox"), ("registerdisp", "xmpp.error"): ("registerhandler", "error"), ("registerdisp", "xmpp.result"): ("registerhandler", "inbox"), ("registerhandler", "outbox"): ("registerdisp", "forward"), ("client", "doregistration"): ("registerdisp", "forward"), ("registerdisp", "outbox"): ("xmpp", "forward"), # Presence ("xmpp", "%s.presence" % XMPP_CLIENT_NS): ("presencedisp", "inbox"), ("presencedisp", "log"): ('logger', "inbox"), ("presencedisp", "xmpp.subscribe"): ("presencehandler", "subscribe"), ("presencedisp", "xmpp.unsubscribe"): ("presencehandler", "unsubscribe"), ("presencehandler", "outbox"): ("presencedisp", "forward"), ("presencehandler", "roster"): ("rosterdisp", "forward"), ("presencedisp", "outbox"): ("xmpp", "forward"), # Roster ("xmpp", "%s.query" % XMPP_ROSTER_NS): ("rosterdisp", "inbox"), ("rosterdisp", "log"): ('logger', "inbox"), ('rosterdisp', 'xmpp.set'): ('rosterhandler', 'pushed'), ('rosterdisp', 'xmpp.result'): ('rosterhandler', 'inbox'), ('rosterhandler', 'result'): ('rosterdisp', 'forward'), ("rosterdisp", "outbox"): ("xmpp", "forward"), # Discovery ("xmpp", "%s.query" % XMPP_DISCO_INFO_NS): ("discodisp", "features.inbox"), ("discodisp", "log"): ('logger', "inbox"), ("discohandler", "features-disco"): ('discodisp', "features.forward"), ("discodisp", "out.features.result"): ('discohandler', "features.result"), ("discodisp", "outbox"): ("xmpp", "forward"), # Message ("xmpp", "%s.message" % XMPP_CLIENT_NS): ("msgdisp", "inbox"), ("msgdisp", "log"): ('logger', "inbox"), ("msgdisp", "xmpp.chat"): ('msgdummyhandler', 'inbox'), ("msgdummyhandler", "outbox"): ('msgdisp', 'forward'), ("msgdisp", "outbox"): ("xmpp", "forward"), ('msgdummyhandler', 'proto') : ('proto_man' , 'inbox'), ('proto_man', 'outbox') : ('msgdummyhandler', 'inbox'), # Activity ("xmpp", "%s.query" % XMPP_LAST_NS): ("activitydisp", "inbox"), ("activitydisp", "log"): ('logger', "inbox"), ("activitydisp", "outbox"): ("xmpp", "forward"), ("activityhandler", 'activity-supported'): ('rosterhandler', 'ask-activity'), ("rosterhandler", 'activity'): ('activitydisp', 'forward'), } ) self.addChildren(self.graph) self.graph.activate() return 1 def main(self): yield self.setup() while 1: while self.dataReady("control"): mes = self.recv("control") if isinstance(mes, str): if mes.strip() == 'quit': self.shutdown() elif isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): self.send(mes, "signal") break while self.dataReady("inbox"): msg = self.recv('inbox') if msg == "quit": self.send(shutdownMicroprocess(), "signal") yield 1 break while self.dataReady("streamfeat"): feat = self.recv('streamfeat') if feat.register and self.register: self.send(Registration(), 'doregistration') elif self.register and not feat.register: print "The server does not support in-band registration. Closing connection." self.abort() else: self.send(feat, 'doauth') while self.dataReady("jid"): self.jid = self.recv('jid') if not self.anyReady(): self.pause() yield 1 yield 1 self.stop() print "You can hit Ctrl-C to shutdown all processes now."
class Client(component): Inboxes = {"inbox" : "", "jid" : "", "streamfeat" : "", "connected" : "", "unhandled" : "", "control" : "Shutdown the client stream"} Outboxes = {"outbox" : "", "forward" : "", "log" : "", "doauth" : "", "signal" : "Shutdown signal", "doregistration" : ""} Domain = None Host = u'localhost' Port = 5222 Sessions = {} def __init__(self, atompub, username, password, domain, resource=u"headstock-client1", server=u'localhost', port=5222, usetls=False, register=False, session_id=None, profile=None): super(Client, self).__init__() self.running = False self.connected = False self.atompub = atompub if not session_id: session_id = generate_unique() self.session_id = session_id self.backplanes = [] self.username = username self.password = password self.jid = JID(self.username, domain, '%s!%s' % (resource, session_id)) self.server = server self.port = port self.client = None self.graph = None self.domain = domain self.usetls = usetls self.register = register self.restartable = False self.profile = profile @staticmethod def start_clients(atompub, users): for username, password in users: profile = atompub.load_profile(username) Client.connect_jabber_user(atompub, username, password, profile) @staticmethod def register_jabber_user(atompub, username, password, profile): c = Client(atompub, unicode(username), unicode(password), domain=Client.Domain, server=Client.Host, port=Client.Port, usetls=False, register=True, profile=profile) Client.Sessions[c.username] = c c.activate() username = unicode('%s.microblogging' % username) c = Client(atompub, unicode(username), unicode(password), domain=Client.Domain, server=Client.Host, port=Client.Port, usetls=False, register=True, profile=profile) Client.Sessions[c.username] = c c.activate() @staticmethod def connect_jabber_user(atompub, username, password, profile): #c = Client(atompub, unicode(username), unicode(password), # domain=Client.Domain, server=Client.Host, port=Client.Port, # usetls=True, register=False, profile=profile) #Client.Sessions[c.username] = c #c.activate() username = unicode('%s.microblogging' % username) c = Client(atompub, unicode(username), unicode(password), domain=Client.Domain, server=Client.Host, port=Client.Port, usetls=False, register=False, profile=profile) Client.Sessions[c.username] = c c.activate() @staticmethod def disconnect_jabber_user(username): if username in Client.Sessions: c = Client.Sessions[username] del Client.Sessions[username] c.shutdown() @staticmethod def get_status(username): return username in Client.Sessions @staticmethod def is_registered(username): if username.lower() in Client.Sessions: return Client.Sessions[username.lower()] return False def passwordLookup(self, jid): return self.password def shutdown(self): #self.send(Presence.to_element(Presence(self.jid, type=u'unavailable')), 'forward') self.send('OUTGOING : </stream:stream>', 'log') self.send('</stream:stream>', 'outbox') self.running = False def abort(self): self.send('OUTGOING : </stream:stream>', 'log') self.send('</stream:stream>', 'outbox') self.running = False def setup(self): self.running = True # Backplanes are like a global entry points that # can be accessible both for publishing and # recieving data. # In other words, a component interested # in advertising to many other components that # something happened may link one of its outbox # to a PublishTo component's inbox. # A component wishing to receive that piece of # information will link one of its inbox # to the SubscribeTo component's outbox. # This helps greatly to make components more # loosely connected but also allows for some data # to be dispatched at once to many (such as when # the server returns the per-session JID that # is of interest for most other components). self.backplanes.append(Backplane("JID.%s" % self.session_id).activate()) # Used to inform components that the session is now active self.backplanes.append(Backplane("BOUND.%s" % self.session_id).activate()) # Used to inform components of the supported features self.backplanes.append(Backplane("DISCO_FEAT.%s" % self.session_id).activate()) sub = SubscribeTo("JID.%s" % self.session_id) self.link((sub, 'outbox'), (self, 'jid')) self.addChildren(sub) sub.activate() sub = SubscribeTo("BOUND.%s" % self.session_id) self.link((sub, 'outbox'), (self, 'connected')) self.addChildren(sub) sub.activate() # Add two outboxes ro the ClientSteam to support specific extensions. ClientStream.Outboxes["%s.query" % XMPP_IBR_NS] = "Registration" ClientStream.Outboxes["%s.query" % XMPP_LAST_NS] = "Activity" ClientStream.Outboxes["%s.query" % XMPP_DISCO_INFO_NS] = "Discovery" ClientStream.Outboxes["%s.query" % XMPP_DISCO_ITEMS_NS] = "PubSub Discovery of Nodes" ClientStream.Outboxes["%s.subscribe" % XMPP_PUBSUB_NS] = "Pubsub subscription handler" ClientStream.Outboxes["%s.unsubscribe" % XMPP_PUBSUB_NS] = "Pubsub unsubscription handler" ClientStream.Outboxes["%s.subscriptions" % XMPP_PUBSUB_NS] = "Pubsub subscriptions handler" ClientStream.Outboxes["%s.affiliations" % XMPP_PUBSUB_NS] = "Pubsub affiliations handler" ClientStream.Outboxes["%s.create" % XMPP_PUBSUB_NS] = "Pubsub node creation handler" ClientStream.Outboxes["%s.purge" % XMPP_PUBSUB_OWNER_NS] = "Pubsub node purge handler" ClientStream.Outboxes["%s.delete" % XMPP_PUBSUB_OWNER_NS] = "Pubsub node delete handler" ClientStream.Outboxes["%s.publish" % XMPP_PUBSUB_NS] = "Pubsub item publication handler" ClientStream.Outboxes["%s.retract" % XMPP_PUBSUB_NS] = "Pubsub item deletion handler" ClientStream.Outboxes["%s.x" % XMPP_PUBSUB_EVENT_NS] = "" ClientStream.Outboxes["%s.event" % XMPP_PUBSUB_EVENT_NS] = "" self.client = ClientStream(self.jid, self.passwordLookup, use_tls=self.usetls) self.addChildren(self.client) self.client.activate() self.graph = Graphline(client = self, logger = Logger(path='./logs/%s.log' % self.username, stdout=True, name=self.session_id), tcp = TCPClient(self.server, self.port), xmlparser = XMLIncrParser(), xmpp = self.client, streamerr = StreamError(), saslerr = SaslError(), discohandler = DiscoHandler(self.jid, self.atompub, self.domain, session_id=self.session_id, profile=self.profile), activityhandler = ActivityHandler(session_id=self.session_id), rosterhandler = RosterHandler(self.jid, session_id=self.session_id), registerhandler = RegistrationHandler(self.username, self.password, self.session_id, profile=self.profile), msgdummyhandler = DummyMessageHandler(session_id=self.session_id, profile=self.profile), presencehandler = PresenceHandler(session_id=self.session_id), itemshandler = ItemsHandler(self.jid, self.atompub, self.domain, session_id=self.session_id, profile=self.profile), pubsubmsgeventhandler = MessageHandler(self.jid, self.atompub, self.domain, session_id=self.session_id, profile=self.profile), presencedisp = PresenceDispatcher(), rosterdisp = RosterDispatcher(), msgdisp = MessageDispatcher(), discodisp = DiscoveryDispatcher(), activitydisp = ActivityDispatcher(), registerdisp = RegisterDispatcher(), pubsubdisp = PubSubDispatcher(), pjid = PublishTo("JID.%s" % self.session_id), pbound = PublishTo("BOUND.%s" % self.session_id), linkages = {('xmpp', 'terminated'): ('client', 'inbox'), ('client', 'forward'): ('xmpp', 'forward'), ('client', 'outbox'): ('tcp', 'inbox'), ('client', 'signal'): ('tcp', 'control'), ("tcp", "outbox") : ("xmlparser", "inbox"), ("xmpp", "starttls") : ("tcp", "makessl"), ("tcp", "sslready") : ("xmpp", "tlssuccess"), ("xmlparser", "outbox") : ("xmpp" , "inbox"), ("xmpp", "outbox") : ("tcp" , "inbox"), ("xmpp", "reset"): ("xmlparser", "reset"), ("client", "log"): ("logger", "inbox"), ("xmpp", "log"): ("logger", "inbox"), ("xmpp", "jid"): ("pjid", "inbox"), ("xmpp", "bound"): ("pbound", "inbox"), ("xmpp", "features"): ("client", "streamfeat"), ("xmpp", "unhandled"): ("client", "unhandled"), ("client", "doauth"): ("xmpp", "auth"), # Registration ("xmpp", "%s.query" % XMPP_IBR_NS): ("registerdisp", "inbox"), ("registerdisp", "log"): ('logger', "inbox"), ("registerdisp", "xmpp.error"): ("registerhandler", "error"), ("registerdisp", "xmpp.result"): ("registerhandler", "inbox"), ("registerhandler", "outbox"): ("registerdisp", "forward"), ("client", "doregistration"): ("registerdisp", "forward"), ("registerdisp", "outbox"): ("xmpp", "forward"), # Presence ("xmpp", "%s.presence" % XMPP_CLIENT_NS): ("presencedisp", "inbox"), ("presencedisp", "log"): ('logger', "inbox"), ("presencedisp", "xmpp.subscribe"): ("presencehandler", "subscribe"), ("presencedisp", "xmpp.unsubscribe"): ("presencehandler", "unsubscribe"), ("presencehandler", "outbox"): ("presencedisp", "forward"), ("presencehandler", "roster"): ("rosterdisp", "forward"), ("presencedisp", "outbox"): ("xmpp", "forward"), # Roster ("xmpp", "%s.query" % XMPP_ROSTER_NS): ("rosterdisp", "inbox"), ("rosterdisp", "log"): ('logger', "inbox"), ('rosterdisp', 'xmpp.set'): ('rosterhandler', 'pushed'), ('rosterdisp', 'xmpp.result'): ('rosterhandler', 'inbox'), ('rosterhandler', 'result'): ('rosterdisp', 'forward'), ('rosterhandler', 'roster-updated'): ('msgdummyhandler', 'roster-received'), ("rosterdisp", "outbox"): ("xmpp", "forward"), # Discovery ("xmpp", "%s.query" % XMPP_DISCO_INFO_NS): ("discodisp", "features.inbox"), ("xmpp", "%s.query" % XMPP_DISCO_ITEMS_NS): ("discodisp", "items.inbox"), ("xmpp", "%s.affiliations" % XMPP_PUBSUB_NS): ("discodisp", "affiliation.inbox"), ("xmpp", "%s.subscriptions" % XMPP_PUBSUB_NS): ("discodisp", "subscription.inbox"), ("discodisp", "log"): ('logger', "inbox"), ("discohandler", "features-disco"): ('discodisp', "features.forward"), ('discohandler', 'items-disco'): ('discodisp', 'items.forward'), ('discohandler', 'subscriptions-disco'): ('discodisp', 'subscription.forward'), ('discohandler', 'affiliations-disco'): ('discodisp', 'affiliation.forward'), ("discodisp", "out.features.result"): ('discohandler', "features.result"), ("discodisp",'subscription.outbox'):('xmpp','forward'), ("discodisp",'affiliation.outbox'):('xmpp','forward'), ("discodisp",'out.subscription.result'): ('discohandler','subscriptions.result'), ("discodisp",'out.affiliation.result'): ('discohandler','affiliations.result'), ("discodisp", 'out.items.result'): ('discohandler', 'items.result'), ("discodisp", 'out.items.error'): ('discohandler', 'items.error'), ("discodisp", "outbox"): ("xmpp", "forward"), # Message ("xmpp", "%s.message" % XMPP_CLIENT_NS): ("msgdisp", "inbox"), ("msgdisp", "log"): ('logger', "inbox"), ("msgdisp", "xmpp.chat"): ('msgdummyhandler', 'inbox'), ("msgdummyhandler", "outbox"): ('msgdisp', 'forward'), ("msgdisp", "outbox"): ("xmpp", "forward"), # Activity ("xmpp", "%s.query" % XMPP_LAST_NS): ("activitydisp", "inbox"), ("activitydisp", "log"): ('logger', "inbox"), ("activitydisp", "outbox"): ("xmpp", "forward"), ("activityhandler", 'activity-supported'): ('rosterhandler', 'ask-activity'), ("rosterhandler", 'activity'): ('activitydisp', 'forward'), # Pubsub ("xmpp", "%s.create" % XMPP_PUBSUB_NS): ("pubsubdisp", "create.inbox"), ("xmpp", "%s.delete" % XMPP_PUBSUB_OWNER_NS): ("pubsubdisp", "delete.inbox"), ("xmpp", "%s.purge" % XMPP_PUBSUB_OWNER_NS): ("pubsubdisp", "purge.inbox"), ("xmpp", "%s.subscribe" % XMPP_PUBSUB_NS): ("pubsubdisp", "subscribe.inbox"), ("xmpp", "%s.unsubscribe" % XMPP_PUBSUB_NS):("pubsubdisp", "unsubscribe.inbox"), ("xmpp", "%s.publish" % XMPP_PUBSUB_NS): ("pubsubdisp", "publish.inbox"), ("xmpp", "%s.retract" % XMPP_PUBSUB_NS): ("pubsubdisp", "retract.inbox"), ("xmpp", "%s.x" % XMPP_PUBSUB_EVENT_NS): ("pubsubdisp", "message.inbox"), ("xmpp", "%s.event" % XMPP_PUBSUB_EVENT_NS): ("pubsubdisp", "message.inbox"), ("pubsubdisp", "log"): ('logger', "inbox"), ("discohandler", "create-node"): ("pubsubdisp", "create.forward"), ("discohandler", "delete-node"): ("pubsubdisp", "delete.forward"), ("discohandler", "subscribe-node"): ("pubsubdisp", "subscribe.forward"), ("discohandler", "unsubscribe-node"): ("pubsubdisp", "unsubscribe.forward"), ("pubsubdisp", "create.outbox"): ("xmpp", "forward"), ("pubsubdisp", "delete.outbox"): ("xmpp", "forward"), ("pubsubdisp", "purge.outbox"): ("xmpp", "forward"), ("pubsubdisp", "subscribe.outbox"): ("xmpp", "forward"), ("pubsubdisp", "unsubscribe.outbox"): ("xmpp", "forward"), ("pubsubdisp", "publish.outbox"): ("xmpp", "forward"), ("pubsubdisp", "retract.outbox"): ("xmpp", "forward"), ("pubsubdisp", "out.create.result"): ("discohandler", "created"), ("pubsubdisp", "out.subscribe.result"): ("discohandler", "subscribed"), ("pubsubdisp", "out.delete.result"): ("discohandler", "deleted"), ("pubsubdisp", "out.create.error"): ("discohandler", "error"), ("pubsubdisp", "out.delete.error"): ("discohandler", "error"), ("pubsubdisp", "out.publish.error"): ("itemshandler", "publish.error"), ("pubsubdisp", "out.retract.error"): ("itemshandler", "retract.error"), ("pubsubdisp", "out.publish.result"): ("itemshandler", "published"), ("pubsubdisp", "out.message"): ('pubsubmsgeventhandler', 'inbox'), ('itemshandler', 'publish'): ('pubsubdisp', 'publish.forward'), ('itemshandler', 'delete'): ('pubsubdisp', 'retract.forward'), ('itemshandler', 'purge'): ('pubsubdisp', 'purge.forward'), ("msgdummyhandler", "PI"): ('itemshandler', 'topublish'), ("msgdummyhandler", "GEO"): ('itemshandler', 'topublish'), ("msgdummyhandler", "DI"): ('itemshandler', 'todelete'), ("msgdummyhandler", "PN"): ('itemshandler', 'topurge'), ("msgdummyhandler", "CN"): ('discohandler', 'docreate'), ("msgdummyhandler", "DN"): ('discohandler', 'dodelete'), ("msgdummyhandler", "SN"): ('discohandler', 'dosubscribe'), ("msgdummyhandler", "UN"): ('discohandler', 'dounsubscribe'), ('pubsubmsgeventhandler', 'items-disco'): ('discodisp', 'items.forward'), } ) self.addChildren(self.graph) self.graph.activate() return 1 def main(self): yield self.setup() while self.running: if self.dataReady("control"): mes = self.recv("control") if isinstance(mes, str): if mes.strip() == 'quit': self.shutdown() elif isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): self.send(mes, "signal") break if self.dataReady("connected"): self.recv('connected') self.connected = True if self.dataReady("unhandled"): msg = self.recv('unhandled') self.send(('UNHANDLED', msg), 'log') if self.dataReady("inbox"): msg = self.recv('inbox') if msg == "quit": self.send(shutdownMicroprocess(), "signal") yield 1 break if self.dataReady("streamfeat"): feat = self.recv('streamfeat') if feat.register and self.register: self.send(Registration(), 'doregistration') elif self.register and not feat.register: print "The server does not support in-band registration. Closing connection." self.abort() else: self.send(feat, 'doauth') if self.dataReady("jid"): self.jid = self.recv('jid') if not self.anyReady(): self.pause() yield 1 yield shutdownMicroprocess(self, self.children, self.backplanes)
class KamaeliaClient(component, BaseClient): Inboxes = {"inbox" : "Incoming data read from the socket", "tcp-control": "Errors bubbling up from the TCPClient component", "tlssuccess" : "If the TLS exchange has succeeded", "control" : "Shutdown the client stream"} Outboxes = {"outbox" : "", "signal" : "Shutdown signal", "starttls": "Initiates the TLS negociation"} def __init__(self, jid, password, hostname='localhost', port=5222, tls=False, registercls=None): super(KamaeliaClient, self).__init__() BaseClient.__init__(self, jid, password, tls, registercls) self.graph = Graphline(client = self, tcp = KTCPClient(hostname, port), linkages = {('client', 'outbox'): ('tcp', 'inbox'), ("tcp", "outbox") : ("client", "inbox"), ("tcp", "signal") : ("client", "tcp-control"), ("client", "starttls") : ("tcp", "makessl"), ("tcp", "sslready") : ("client", "tlssuccess")}) self.addChildren(self.graph) self.link((self, 'signal'), (self.graph, 'control')) def send_raw_stanza(self, stanza): self.send(stanza, 'outbox') def start_tls(self): self.send('', 'starttls') def start(self): """ Starts the client by activating the component. """ self.running = True self.activate() def stop(self): BaseClient.stop(self) ########################################## # Axon specific API ########################################## def initializeComponents(self): self.graph.activate() return 1 def main(self): yield self.initializeComponents() yield 1 self.send_stream_header() self.running = True while self.running: if self.dataReady("tcp-control"): mes = self.recv("tcp-control") if isinstance(mes, shutdownMicroprocess) or \ isinstance(mes, producerFinished): self.stopping() self.log(mes.message, prefix='ERROR') self.socket_error(mes.message) self.send(shutdownMicroprocess(), "signal") yield 1 self.running = False if self.dataReady("control"): mes = self.recv("control") if isinstance(mes, shutdownMicroprocess) or \ isinstance(mes, producerFinished): self.stopping() self.send(shutdownMicroprocess(), "signal") yield 1 self.running = False if self.dataReady("tlssuccess"): self.recv("tlssuccess") yield 1 self.tls_ok() yield 1 if self.dataReady("inbox"): data = self.recv('inbox') try: self.parser.feed(data) except SAXParseException, exc: self.log(traceback=True) if self.running and not self.anyReady(): self.pause() yield 1 self.cleanup() self.send(shutdownMicroprocess(), "signal") yield 1 self.graph.removeChild(self) while not self.graph.childrenDone(): if not self.anyReady(): self.graph.pause() yield 1 while not self.childrenDone(): if not self.anyReady(): self.pause() yield 1 self.graph = None self.terminated()