1 # Copyright (c) 2009, 2010, 2011 Nicira Networks
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
26 def handle_rpc(rpc, msg):
30 if msg.type == ovs.jsonrpc.Message.T_REQUEST:
31 if msg.method == "echo":
32 reply = ovs.jsonrpc.Message.create_reply(msg.params, msg.id)
34 reply = ovs.jsonrpc.Message.create_error(
35 {"error": "unknown method"}, msg.id)
36 sys.stderr.write("unknown request %s" % msg.method)
37 elif msg.type == ovs.jsonrpc.Message.T_NOTIFY:
38 if msg.method == "shutdown":
41 rpc.error(errno.ENOTTY)
42 sys.stderr.write("unknown notification %s" % msg.method)
44 rpc.error(errno.EPROTO)
45 sys.stderr.write("unsolicited JSON-RPC reply or error\n")
52 error, pstream = ovs.stream.PassiveStream.open(name)
54 sys.stderr.write("could not listen on \"%s\": %s\n"
55 % (name, os.strerror(error)))
58 ovs.daemon.daemonize()
63 # Accept new connections.
64 error, stream = pstream.accept()
66 rpcs.append(ovs.jsonrpc.Connection(stream))
67 elif error != errno.EAGAIN:
68 sys.stderr.write("PassiveStream.accept() failed\n")
71 # Service existing connections.
77 if not rpc.get_backlog():
78 error, msg = rpc.recv()
80 if handle_rpc(rpc, msg):
83 error = rpc.get_status()
87 rpcs = [rpc for rpc in rpcs if not rpc in dead_rpcs]
92 poller = ovs.poller.Poller()
96 if not rpc.get_backlog():
101 def do_request(name, method, params_string):
102 params = ovs.json.from_string(params_string)
103 msg = ovs.jsonrpc.Message.create_request(method, params)
106 sys.stderr.write("not a valid JSON-RPC request: %s\n" % s)
109 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
111 sys.stderr.write("could not open \"%s\": %s\n"
112 % (name, os.strerror(error)))
115 rpc = ovs.jsonrpc.Connection(stream)
117 error = rpc.send(msg)
119 sys.stderr.write("could not send request: %s\n" % os.strerror(error))
122 error, msg = rpc.recv_block()
124 sys.stderr.write("error waiting for reply: %s\n" % os.strerror(error))
127 print ovs.json.to_string(msg.to_json())
131 def do_notify(name, method, params_string):
132 params = ovs.json.from_string(params_string)
133 msg = ovs.jsonrpc.Message.create_notify(method, params)
136 sys.stderr.write("not a valid JSON-RPC notification: %s\n" % s)
139 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
141 sys.stderr.write("could not open \"%s\": %s\n"
142 % (name, os.strerror(error)))
145 rpc = ovs.jsonrpc.Connection(stream)
147 error = rpc.send_block(msg)
149 sys.stderr.write("could not send notification: %s\n"
150 % os.strerror(error))
157 options, args = getopt.gnu_getopt(
158 argv[1:], 'h', ["help"] + ovs.daemon.LONG_OPTIONS)
159 except getopt.GetoptError, geo:
160 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
163 for key, value in options:
164 if key in ['h', '--help']:
166 elif not ovs.daemon.parse_opt(key, value):
167 sys.stderr.write("%s: unhandled option %s\n"
168 % (ovs.util.PROGRAM_NAME, key))
171 commands = {"listen": (do_listen, 1),
172 "request": (do_request, 3),
173 "notify": (do_notify, 3),
174 "help": (usage, (0,))}
176 command_name = args[0]
178 if not command_name in commands:
179 sys.stderr.write("%s: unknown command \"%s\" "
180 "(use --help for help)\n" % (argv0, command_name))
183 func, n_args = commands[command_name]
184 if type(n_args) == tuple:
185 if len(args) < n_args[0]:
186 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
188 % (argv0, command_name, n_args, len(args)))
190 elif type(n_args) == int:
191 if len(args) != n_args:
192 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
194 % (argv0, command_name, n_args, len(args)))
202 sys.stdout.write("""\
203 %s: JSON-RPC test utility for Python
204 usage: %s [OPTIONS] COMMAND [ARG...]
205 listen LOCAL listen for connections on LOCAL
206 request REMOTE METHOD PARAMS send request, print reply
207 notify REMOTE METHOD PARAMS send notification and exit
208 """ % (ovs.util.PROGRAM_NAME, ovs.util.PROGRAM_NAME))
209 ovs.stream.usage("JSON-RPC", True, True, True)
213 -h, --help display this help message
217 if __name__ == '__main__':