├── .gitignore
├── AUTHORS
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
├── about.md
├── changelog.md
├── cqrs.md
├── helloworld.md
├── index.md
├── javascript.md
└── python.md
├── goczmq
├── .Rhistory
├── README.md
└── helloworld
│ └── main.go
├── lzmq
├── README.md
└── SimpleHelloWorld
│ ├── client.lua
│ ├── mt_run.lua
│ └── server.lua
├── mkdocs.yml
├── netmq
└── HelloWord
│ ├── HelloWorld.cs
│ ├── netmq.cookbook.csproj
│ ├── netmq.sln
│ └── packages.config
└── pyzmq
├── cqrs
├── .gitignore
├── requirements.txt
└── src
│ ├── core
│ ├── __init__.py
│ ├── connectors.py
│ ├── handlers.py
│ └── parameters.py
│ ├── requirements
│ ├── development.txt
│ └── production.txt
│ └── tests
│ ├── __init__.py
│ └── core_tests.py
└── helloword
└── src
├── helloword.py
├── requirements.txt
└── requirements
├── development.txt
└── production.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Python template
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | env/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .coverage
43 | .coverage.*
44 | .cache
45 | nosetests.xml
46 | coverage.xml
47 | *,cover
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 |
56 | # Sphinx documentation
57 | docs/_build/
58 |
59 | # PyBuilder
60 | target/
61 |
62 | #.idea/*
63 |
64 | #mkdocs generated files
65 | site/
66 |
67 | # netmq projects
68 | packages/**
69 |
70 | .idea/**
71 |
72 | bin/**
73 |
74 | obj/**
75 |
76 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeromq/cookbook/da97256ec8bcaaf316fbf614c21b6e7378e26d69/AUTHORS
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the ZeroMQ Cookbook
2 |
3 | The contributors are listed in AUTHORS (add yourself). This project uses the MIT/X11 license, see LICENSE.
4 |
5 | Please read these documents BEFORE you send a patch:
6 |
7 | * This project uses the [C4.1 (Collective Code Construction Contract)](http://rfc.zeromq.org/spec:22) process for contributions. Please read this if you are unfamiliar with it.
8 |
9 | * Please stick to the recipe filenames for all source code. One recipe = one source.
10 |
11 | * One directory per language binding. We'll deal with versions later.
12 |
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) the Contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ZeroMQ Cookbook
2 |
3 | Recipes:
4 |
5 | * [Hello World](docs/helloworld.md)
6 | * [CQRS](docs/cqrs.md)
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/about.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeromq/cookbook/da97256ec8bcaaf316fbf614c21b6e7378e26d69/docs/about.md
--------------------------------------------------------------------------------
/docs/changelog.md:
--------------------------------------------------------------------------------
1 | * 29-11-2015 - New "scalable" structure to help organize all recipes language and the recipes itself.
--------------------------------------------------------------------------------
/docs/cqrs.md:
--------------------------------------------------------------------------------
1 | Problem: We need a reference implementation of CQRS style architecture.
2 | =================================================
3 |
4 | We need a reference implementation of CQRS style architecture.
5 |
6 | ## Design
7 | 
8 |
9 | ## Features
10 | ###1. Basic communication
11 | ###2. Error handling
12 | - Reliability
13 | ###3. Communication messages
14 | - Business messages
15 | - Business errors
16 | ###4. Domain commands handling
17 | ###5. Domain events propagation
18 | ###6. Domain events persistence
19 | ###7. Domain events projections
20 |
21 | ## Implementations:
22 | * [PyZMQ](https://github.com/zeromq/cookbook/blob/master/pyzmq/cqrs)
23 |
24 | ## References
25 | - [CQRS](http://martinfowler.com/bliki/CQRS.html) - http://martinfowler.com/bliki/CQRS.html
26 |
27 | - [Clarified CQRS](http://udidahan.com/2009/12/09/clarified-cqrs/) - http://udidahan.com/2009/12/09/clarified-cqrs/
--------------------------------------------------------------------------------
/docs/helloworld.md:
--------------------------------------------------------------------------------
1 | Problem: I don't know zeromq and want to learn the simplest usage, show me some code
2 | ==============================================
3 |
4 | The simplest example is client-server. Client sends "Hello" and server replies with "World".
5 |
6 | Design
7 | ======
8 |
9 | The recipe is divided to a client and server, client connects to the server and send a request, server binds and sending a reply.
10 |
11 | Client uses a CLIENT socket type.
12 | Server uses a SERVER socket type.
13 |
14 | Clients steps:
15 |
16 | 1. Create a CLIENT socket
17 | 2. Connect to the server
18 | 3. Send "Hello" request message
19 | 4. Receive reply message
20 |
21 | Server steps:
22 |
23 | 1. Create SERVER socket
24 | 2. Binds the socket
25 | 3. Receive request message
26 | 4. Send "World" reply message
27 |
28 | Implementations:
29 | ===================
30 | * [GOCZMQ](https://github.com/zeromq/cookbook/blob/master/goczmq/simple_helloworld_test.go)
31 | * [NetMQ](https://github.com/zeromq/cookbook/blob/master/netmq/HelloWorld.cs)
32 | * [PyZMQ](https://github.com/zeromq/cookbook/blob/master/pyzmq/helloword)
33 |
34 | References:
35 | ==============
36 | * [NetMQ](http://netmq.readthedocs.org/en/latest/)
37 | * [goczmq](https://github.com/zeromq/goczmq)
38 | * [PyZMQ](http://learning-0mq-with-pyzmq.readthedocs.org/en/latest/pyzmq/patterns/client_server.html)
39 | * [PyZMQ Examples](https://github.com/zeromq/pyzmq/blob/master/examples/)
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # ZeroMQ Cookbook
2 |
3 | Recipes:
4 |
5 | * [Hello World](helloworld.md)
6 | * [CQRS](cqrs.md)
--------------------------------------------------------------------------------
/docs/javascript.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeromq/cookbook/da97256ec8bcaaf316fbf614c21b6e7378e26d69/docs/javascript.md
--------------------------------------------------------------------------------
/docs/python.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeromq/cookbook/da97256ec8bcaaf316fbf614c21b6e7378e26d69/docs/python.md
--------------------------------------------------------------------------------
/goczmq/.Rhistory:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeromq/cookbook/da97256ec8bcaaf316fbf614c21b6e7378e26d69/goczmq/.Rhistory
--------------------------------------------------------------------------------
/goczmq/README.md:
--------------------------------------------------------------------------------
1 | # GoCZMQ
2 |
3 | This directory contains cookbook examples for the [GoCZMQ](http://github.com/zeromq/goczmq) Go bindings for [CZMQ](http://github.com/zeromq/czmq).
4 |
--------------------------------------------------------------------------------
/goczmq/helloworld/main.go:
--------------------------------------------------------------------------------
1 | /*
2 | Problem: We want to send a message and receive a reply
3 |
4 | Solution: Let's write a simple "Hello World" client and server.
5 | We'll write them as go tests, so that we can verify that they
6 | work. To run this test, you can run "go test -run SimpleHelloWorld"
7 | in the same directory as this file.
8 | */
9 |
10 | package main
11 |
12 | import (
13 | "log"
14 |
15 | "github.com/zeromq/goczmq"
16 | )
17 |
18 | // SimpleHelloWorldClient does the following:
19 | // * Creates a ZMQ_REQ socket
20 | // * Sends a "Hello" message
21 | // * Waits for a "World" reply
22 | func SimpleHelloWorldClient() {
23 | log.Printf("client starting...")
24 |
25 | // Create a ZMQ_REQ client using a "smart constructor".
26 | // See: https://godoc.org/github.com/zeromq/goczmq#NewReq
27 |
28 | client, err := goczmq.NewReq("tcp://localhost:5555")
29 | if err != nil {
30 | log.Fatalf("client.NewReq error: %s", err)
31 | }
32 |
33 | // Here, we make sure the socket is destroyed
34 | // when this function exits. While Go is a garbage
35 | // collected language, we're binding a C library,
36 | // so we need to make sure to clean up.
37 |
38 | defer client.Destroy()
39 |
40 | // Let's create a request message. GoCZMQ uses slices
41 | // of byte slices for messages, because they map
42 | // very simply to ZeroMQ "frames".
43 |
44 | request := [][]byte{[]byte("Hello")}
45 |
46 | // Send the message and check for any errors.
47 |
48 | err = client.SendMessage(request)
49 | if err != nil {
50 | log.Fatalf("client.SendMessage error: %s", err)
51 | }
52 |
53 | log.Printf("client.SendMessage '%s'", request)
54 |
55 | // Receive the reply message from the server. Note that
56 | // this RecvMessage() call will block forever waiting
57 | // for a message.
58 |
59 | reply, err := client.RecvMessage()
60 | if err != nil {
61 | log.Fatalf("client.RecvMessage error: %s", err)
62 | }
63 |
64 | log.Printf("client.RecvMessage: '%s'", reply)
65 | }
66 |
67 | // SimpleHelloWorldServer does the following:
68 | // * Creates a ZMQ_REP socket
69 | // * Waits for a "Hello" request
70 | // * Sends a "World" reply
71 | func SimpleHelloWorldServer() {
72 | log.Printf("server starting...")
73 |
74 | // Create a ZMQ_REP server using a "smart constructor".
75 | // See: https://godoc.org/github.com/zeromq/goczmq#NewRep
76 |
77 | server, err := goczmq.NewRep("tcp://*:5555")
78 | if err != nil {
79 | log.Fatalf("server.NewRep error: %s", err)
80 | }
81 |
82 | // Here, we make sure the socket is destroyed
83 | // when this function exits. While Go is a garbage
84 | // collected language, we're binding a C library,
85 | // so we need to make sure to clean up.
86 |
87 | defer server.Destroy()
88 |
89 | // Let's wait for a message from a client. Note that
90 | // this RecvMessage call will block forever waiting.
91 |
92 | request, err := server.RecvMessage()
93 | if err != nil {
94 | log.Fatalf("server.RecvMessage error: %s", err)
95 | }
96 |
97 | log.Printf("server.RecvMessage: '%s'", request)
98 |
99 | // Here we create a reply message. GoCZMQ uses slices
100 | // of byte slices for messages, because they map
101 | // very simply to ZeroMQ "frames".
102 |
103 | reply := [][]byte{[]byte("World")}
104 |
105 | // Send the message and check for any errors.
106 |
107 | err = server.SendMessage(reply)
108 | if err != nil {
109 | log.Fatalf("server.SendMessage error: %s", err)
110 | }
111 |
112 | log.Printf("server.SendMessage: '%s'", reply)
113 | }
114 |
115 | // TestSimpleHelloWorld starts SimpleHelloWorldServer in
116 | // a goroutine, then starts a SimpleHelloWorldClient
117 | func main() {
118 | go SimpleHelloWorldServer()
119 | SimpleHelloWorldClient()
120 | }
121 |
--------------------------------------------------------------------------------
/lzmq/README.md:
--------------------------------------------------------------------------------
1 | # lzmq
2 |
3 | This directory contains cookbook examples for the [lzmq](http://github.com/zeromq/lzmq) Lua binding.
4 |
--------------------------------------------------------------------------------
/lzmq/SimpleHelloWorld/client.lua:
--------------------------------------------------------------------------------
1 | local zthreads = require "lzmq.threads"
2 |
3 | -- If we run as thread we get global context
4 | -- If we run as process we create new context
5 | local ctx = zthreads.context()
6 |
7 | -- Create new REQ socket and connect to the server
8 | local skt, err = ctx:socket{"REQ",
9 | connect = "tcp://127.0.0.1:5555"
10 | }
11 | if not skt then
12 | print("Can not create client socket:", err)
13 | os.exit(1)
14 | end
15 |
16 | -- Send message
17 | local ok, err = skt:send("Hello")
18 | if not ok then
19 | print("Can not send hello message:", err)
20 | os.exit(1)
21 | end
22 |
23 | -- Recv server response
24 | local msg, err = skt:recv()
25 | if not msg then
26 | print("Can not recv server response:", err)
27 | os.exit(1)
28 | end
29 |
30 | print("Client recv message:", msg)
31 |
32 |
--------------------------------------------------------------------------------
/lzmq/SimpleHelloWorld/mt_run.lua:
--------------------------------------------------------------------------------
1 | -- Run HelloWorld example in multithreaded environment
2 |
3 | local zthreads = require "lzmq.threads"
4 |
5 | -- all threads use same global ZMQ context
6 |
7 | -- run server in separate thread
8 | local server = zthreads.xfork("@./server.lua"):start()
9 |
10 | -- run client in separate thread
11 | local client = zthreads.xfork("@./client.lua"):start()
12 |
13 | -- wait server thread
14 | server:join()
15 |
16 | -- wait client thread
17 | client:join()
18 |
--------------------------------------------------------------------------------
/lzmq/SimpleHelloWorld/server.lua:
--------------------------------------------------------------------------------
1 | local zthreads = require "lzmq.threads"
2 |
3 | -- If we run as thread we get global context
4 | -- If we run as process we create new context
5 | local ctx = zthreads.context()
6 |
7 | -- Create new REP socket and bind on interface
8 | local skt, err = ctx:socket{"REP",
9 | bind = "tcp://*:5555"
10 | }
11 | if not skt then
12 | print("Can not create server socket:", err)
13 | os.exit(1)
14 | end
15 |
16 | -- Send message
17 | local msg, err = skt:recv()
18 | if not msg then
19 | print("Can not recv hello message:", err)
20 | os.exit(1)
21 | end
22 |
23 | print("Server recv message:", msg)
24 |
25 | -- Recv server response
26 | local ok, err = skt:send("World")
27 | if not ok then
28 | print("Can not send server response:", err)
29 | os.exit(1)
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: Cookbook
2 | pages:
3 | - Home: index.md
4 | - Recipes:
5 | - Helloworld: helloworld.md
6 | - CQRS Style Architecture: cqrs.md
7 |
8 | - Changelog: changelog.md
9 |
10 | theme: readthedocs
11 | repo_url: https://github.com/zeromq/cookbook/
12 | markdown_extensions: [codehilite]
13 |
--------------------------------------------------------------------------------
/netmq/HelloWord/HelloWorld.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using NetMQ;
7 | using NUnit.Framework;
8 |
9 | namespace netmq
10 | {
11 | ///
12 | /// Problem: We want to send a message and receive a reply
13 | /// Solution: Let's write a simple "Hello World" client and server.
14 | ///
15 | [TestFixture]
16 | public class HelloWorld
17 | {
18 | [Test]
19 | public void HelloWorldTest()
20 | {
21 | // context must be created to create sockets, one context per application
22 | using (NetMQContext context = NetMQContext.Create())
23 | {
24 | Task.Factory.StartNew(() => Server(context));
25 | Client(context);
26 | }
27 | }
28 |
29 | ///
30 | /// Client does the following:
31 | /// * Creates a Request socket
32 | /// * Sends a "Hello" message
33 | /// * Waits for a "World" reply
34 | ///
35 | ///
36 | private void Client(NetMQContext context)
37 | {
38 | // creating the request socket inside using to automatically dispose the socket
39 | using (var request = context.CreateRequestSocket())
40 | {
41 | // connecting to the response socket
42 | request.Connect("tcp://localhost:5555");
43 |
44 | // sending a request message, SendFrame has multiple overload you can use"
45 | request.SendFrame("Hello");
46 |
47 | // Receive the reply message from the server. Note that
48 | // this ReceiveFrameString() call will block forever waiting
49 | // for a message.
50 | var reply = request.ReceiveFrameString();
51 |
52 | Assert.That(reply == "World");
53 | }
54 | }
55 |
56 | ///
57 | /// SimpleHelloWorldServer does the following:
58 | /// * Creates a Response socket
59 | /// * Waits for a "Hello" request
60 | /// * Sends a "World" reply
61 | ///
62 | ///
63 | private void Server(NetMQContext context)
64 | {
65 | // create the response socket
66 | using (var response = context.CreateResponseSocket())
67 | {
68 | // bind the response socket, binds make the socket the "server"
69 | // * can be used to bind to all IP addresses
70 | response.Bind("tcp://*:5555");
71 |
72 | // response socket must first receive a message and only then reply
73 | string request = response.ReceiveFrameString();
74 |
75 | Assert.That(request == "Hello");
76 |
77 | response.SendFrame("World");
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/netmq/HelloWord/netmq.cookbook.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CE3F477A-61BF-4C93-8C75-4AF58697A0A5}
8 | Library
9 | Properties
10 | netmq.cookbook
11 | netmq.cookbook
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | packages\AsyncIO.0.1.17.0\lib\net40\AsyncIO.dll
35 |
36 |
37 | packages\NetMQ.3.3.2.2\lib\net40\NetMQ.dll
38 |
39 |
40 | packages\NUnit.2.6.4\lib\nunit.framework.dll
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
60 |
--------------------------------------------------------------------------------
/netmq/HelloWord/netmq.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "netmq.cookbook", "netmq.cookbook.csproj", "{CE3F477A-61BF-4C93-8C75-4AF58697A0A5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {CE3F477A-61BF-4C93-8C75-4AF58697A0A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {CE3F477A-61BF-4C93-8C75-4AF58697A0A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {CE3F477A-61BF-4C93-8C75-4AF58697A0A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {CE3F477A-61BF-4C93-8C75-4AF58697A0A5}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/netmq/HelloWord/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Python template
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | env/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .coverage
43 | .coverage.*
44 | .cache
45 | nosetests.xml
46 | coverage.xml
47 | *,cover
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 |
56 | # Sphinx documentation
57 | docs/_build/
58 |
59 | # PyBuilder
60 | target/
61 |
62 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/requirements.txt:
--------------------------------------------------------------------------------
1 | -r requirements/development.txt
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/core/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright (c) the Contributors
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | # this software and associated documentation files (the "Software"), to deal in
7 | # the Software without restriction, including without limitation the rights to
8 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | # the Software, and to permit persons to whom the Software is furnished to do so,
10 | # subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | #
22 |
23 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/core/connectors.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright (c) the Contributors
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | # this software and associated documentation files (the "Software"), to deal in
7 | # the Software without restriction, including without limitation the rights to
8 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | # the Software, and to permit persons to whom the Software is furnished to do so,
10 | # subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | #
22 |
23 | import logging
24 | import zmq
25 | from zmq.eventloop import zmqstream
26 |
27 | logger = logging.getLogger('cqrs-core')
28 |
29 |
30 | class Connector:
31 |
32 | def __init__(self, name, end_point, context=None):
33 | self._context = context or zmq.Context.instance()
34 | self._name = name
35 | self._end_point = end_point
36 |
37 | logger.info('command handler initialized')
38 |
39 | def _on_recv(self, stream, msg):
40 | logger.info('data received')
41 |
42 |
43 | class CommandHandlerConnector(Connector):
44 |
45 | def __init__(self, name, end_point, context=None):
46 | super(CommandHandlerConnector, self).__init__(name, end_point, context)
47 | self._sockt = self._context.socket(zmq.REQ)
48 | self._stream = zmqstream.ZMQStream(self._sockt)
49 | self._stream.on_recv_stream(self._on_recv)
50 |
51 | def connect(self):
52 | self._sockt.connect(self._end_point)
53 |
54 | def send(self, data):
55 | self._sockt.send_pyobj(data)
56 |
57 |
58 | class QueryHandlerConnector(Connector):
59 |
60 | def __init__(self, name, end_point, context=None):
61 | super(QueryHandlerConnector, self).__init__(name, end_point, context)
62 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/core/handlers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright (c) the Contributors
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | # this software and associated documentation files (the "Software"), to deal in
7 | # the Software without restriction, including without limitation the rights to
8 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | # the Software, and to permit persons to whom the Software is furnished to do so,
10 | # subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | #
22 |
23 | import logging
24 | import zmq
25 | from zmq.eventloop import zmqstream
26 |
27 | logger = logging.getLogger('cqrs-core')
28 |
29 |
30 | class CommandHandler:
31 |
32 | def __init__(self, registry, name, end_point, sockt):
33 | self._name = name
34 | self._end_point = end_point
35 | self._stream = zmqstream.ZMQStream(sockt)
36 | self._registry = registry
37 | logger.info('command handler initialized')
38 |
39 | @property
40 | def get_name(self):
41 | return self._name
42 |
43 | def start(self):
44 | self._stream.on_recv_stream(self._on_recv)
45 | self._stream.on_send_stream(self._on_send)
46 | self._stream.bind(self._end_point)
47 | logger.info('command request started')
48 |
49 | def stop(self):
50 | self._stream.stop_on_send()
51 | self._stream.stop_on_recv()
52 | logger.info('command request stopped')
53 |
54 | def _on_recv(self, stream, msg):
55 | logger.info('data received')
56 |
57 | def _on_send(self, stream, msg, status):
58 | pass
59 |
60 | def on_validation(self):
61 | return False
62 |
63 | def on_execution(self):
64 | pass
65 |
66 | def handle(self, arguments):
67 |
68 | if self.on_validation(arguments):
69 | self.on_execution()
70 |
71 |
72 | class CommandHandlerRegistry:
73 |
74 | def __init__(self, context=None):
75 | self._context = context or zmq.Context.instance()
76 | self._commands = {}
77 |
78 | def createCommandHandler(self, name, end_point):
79 |
80 | if not self._commands.get(end_point):
81 | s = self._context.socket(zmq.ROUTER)
82 | self._commands[end_point] = CommandHandler(self, name, end_point, s)
83 | return self._commands.get(end_point)
84 |
85 | def add_command(self, end_point):
86 | pass
87 |
88 |
89 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/core/parameters.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright (c) the Contributors
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | # this software and associated documentation files (the "Software"), to deal in
7 | # the Software without restriction, including without limitation the rights to
8 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | # the Software, and to permit persons to whom the Software is furnished to do so,
10 | # subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | #
22 |
23 | import logging
24 | import zmq
25 | from zmq.eventloop import zmqstream
26 |
27 | logger = logging.getLogger('cqrs-core')
28 |
29 |
30 | class CommandRequest:
31 |
32 | def __init__(self, name):
33 | self.name = name
34 |
35 | @property
36 | def get_name(self):
37 | return self.name
38 |
39 |
40 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/requirements/development.txt:
--------------------------------------------------------------------------------
1 | pyzmq==14.5.0
2 | nose==1.3.7
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/requirements/production.txt:
--------------------------------------------------------------------------------
1 | pyzmq==14.5.0
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/tests/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'adriano'
2 |
--------------------------------------------------------------------------------
/pyzmq/cqrs/src/tests/core_tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright (c) the Contributors
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | # this software and associated documentation files (the "Software"), to deal in
7 | # the Software without restriction, including without limitation the rights to
8 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | # the Software, and to permit persons to whom the Software is furnished to do so,
10 | # subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | #
22 |
23 | import unittest
24 | import nose
25 | from core.handlers import CommandHandler, CommandHandlerRegistry
26 |
27 |
28 | class CommandRegistryTest(unittest.TestCase):
29 |
30 | def test_core(self):
31 | registry = CommandHandlerRegistry()
32 | handler = registry.createCommandHandler('test', 'tcp://*:5555')
33 |
34 | handler.start()
35 |
36 |
37 |
38 | handler.stop()
39 |
40 | nose.tools.ok_(True)
41 |
42 |
--------------------------------------------------------------------------------
/pyzmq/helloword/src/helloword.py:
--------------------------------------------------------------------------------
1 | """Example using zmq with asyncio coroutines"""
2 | # Copyright (c) PyZMQ Developers.
3 | # This example is in the public domain (CC-0)
4 | import asyncio
5 | import zmq
6 | import zmq.asyncio
7 | from zmq.error import ZMQError
8 |
9 |
10 | context = zmq.Context()
11 | endpoint = 'tcp://127.0.0.1:5555'
12 |
13 | srv = context.socket(zmq.REP)
14 | clt = context.socket(zmq.REQ)
15 |
16 | srv.bind(endpoint)
17 | print('server online')
18 |
19 | print("Connecting to server...")
20 | clt.connect(endpoint)
21 |
22 | while True:
23 | clt.send_string("Hello")
24 |
25 | message = srv.recv_string()
26 | print("server: {0} client".format(message))
27 | srv.send_string('World')
28 |
29 | msg = clt.recv_string()
30 | print('Thank you: Hello {0}'.format(msg))
31 |
32 |
--------------------------------------------------------------------------------
/pyzmq/helloword/src/requirements.txt:
--------------------------------------------------------------------------------
1 | -r requirements/development.txt
--------------------------------------------------------------------------------
/pyzmq/helloword/src/requirements/development.txt:
--------------------------------------------------------------------------------
1 | zmq==15.1.0
2 |
--------------------------------------------------------------------------------
/pyzmq/helloword/src/requirements/production.txt:
--------------------------------------------------------------------------------
1 | pyzmq==15.1.0
--------------------------------------------------------------------------------