Skip to content

Commit 3cb1ce6

Browse files
committed
Adds Message Queue Service Manager/Connection Class
This was a bit of a difficult one because message queue is an altogether different API and don't support all the same ways of authenticating as the core SoftLayer API can and certainly supports username/API key auth differently. The Message Queue CLI module has been refactored to use the new code and is probably a good reference.
1 parent ef3b524 commit 3cb1ce6

7 files changed

Lines changed: 892 additions & 48 deletions

File tree

SoftLayer/API.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ def __getitem__(self, name):
268268
:param name: The name of the service. E.G. Account
269269
270270
Usage:
271+
>>> client = SoftLayer.Client()
271272
>>> client['Account']
272273
<Service: Account>
273274
@@ -286,6 +287,7 @@ def call(self, service, method, *args, **kwargs):
286287
:param service: the name of the SoftLayer API service
287288
288289
Usage:
290+
>>> client = SoftLayer.Client()
289291
>>> client['Account'].getVirtualGuests(mask="id", limit=10)
290292
[...]
291293

SoftLayer/CLI/modules/messaging.py

Lines changed: 104 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,31 @@
44
Manage SoftLayer Message Queue
55
66
The available commands are:
7-
list-accounts List all queue accounts
8-
queue Queue-related commands
9-
topic Topic-related commands
7+
list-accounts List all queue accounts
8+
list-endpoints List all service endpoints
9+
ping Ping the service
10+
queue Queue-related commands
11+
topic Topic-related commands
1012
"""
1113
# :copyright: (c) 2013, SoftLayer Technologies, Inc. All rights reserved.
1214
# :license: BSD, see LICENSE for more details.
1315
# from SoftLayer import NetworkManager
1416
import sys
1517

18+
from SoftLayer import MessagingManager
1619
from SoftLayer.CLI import CLIRunnable, Table
17-
from SoftLayer.CLI.helpers import CLIAbort, listing, ArgumentError
20+
from SoftLayer.CLI.helpers import CLIAbort, listing, ArgumentError, blank
1821

19-
try:
20-
import softlayer_messaging
21-
except ImportError:
22-
raise CLIAbort("""This functionality requires the softlayer_messaging package.
23-
Run 'pip install softlayer_messaging' to install.""")
22+
23+
COMMON_MESSAGING_ARGS = """Service Options:
24+
--endpoint=NAME Endpoint name
25+
--network=TYPE Network type, [Options: public, private]
26+
"""
2427

2528

26-
def get_mq_client(account_id, env):
27-
client = softlayer_messaging.get_client(account_id)
28-
client.authenticate(env.config.get('username'), env.config.get('api_key'))
29-
return client
29+
def get_mq_client(manager, account_id, env):
30+
return manager.get_connection(
31+
account_id, env.config.get('username'), env.config.get('api_key'))
3032

3133

3234
class ListAccounts(CLIRunnable):
@@ -40,8 +42,8 @@ class ListAccounts(CLIRunnable):
4042

4143
@staticmethod
4244
def execute(client, args):
43-
accounts = client['Account'].getMessageQueueAccounts(
44-
mask='id,name,status,nodes')
45+
manager = MessagingManager(client)
46+
accounts = manager.list_accounts()
4547

4648
t = Table([
4749
'id', 'name', 'status'
@@ -56,6 +58,53 @@ def execute(client, args):
5658
return t
5759

5860

61+
class ListEndpoints(CLIRunnable):
62+
"""
63+
usage: sl messaging list-endpoints [options]
64+
65+
List SoftLayer Message Queue Endpoints
66+
67+
"""
68+
action = 'list-endpoints'
69+
70+
@staticmethod
71+
def execute(client, args):
72+
manager = MessagingManager(client)
73+
regions = manager.get_endpoints()
74+
75+
t = Table([
76+
'name', 'public', 'private'
77+
])
78+
for region, endpoints in regions.items():
79+
t.add_row([
80+
region,
81+
endpoints.get('public') or blank(),
82+
endpoints.get('private') or blank(),
83+
])
84+
85+
return t
86+
87+
88+
class Ping(CLIRunnable):
89+
__doc__ = """
90+
usage: sl messaging ping [options]
91+
92+
Ping the SoftLayer Message Queue service
93+
94+
""" + COMMON_MESSAGING_ARGS
95+
action = 'ping'
96+
97+
@staticmethod
98+
def execute(client, args):
99+
manager = MessagingManager(client)
100+
ok = manager.ping(
101+
endpoint_name=args['--endpoint'], network=args['--network'])
102+
if ok:
103+
return 'OK'
104+
else:
105+
CLIAbort('Ping failed')
106+
107+
59108
def queue_table(queue):
60109
t = Table(['property', 'value'])
61110
t.align['property'] = 'r'
@@ -106,7 +155,7 @@ def subscription_table(sub):
106155

107156

108157
class Queue(CLIRunnable):
109-
"""
158+
__doc__ = """
110159
usage: sl messaging queue list <account_id> [options]
111160
sl messaging queue detail <account_id> <queue_name> [options]
112161
sl messaging queue create <account_id> <queue_name> [options]
@@ -127,17 +176,20 @@ class Queue(CLIRunnable):
127176
--force Flag to force the deletion of the queue even when there are messages
128177
129178
Pop Options:
130-
--count=NUM Count of messages to pop
131-
"""
179+
--count=NUM Count of messages to pop
180+
--delete-after Remove popped messages from the queue
181+
182+
""" + COMMON_MESSAGING_ARGS
132183
action = 'queue'
133184

134185
@classmethod
135186
def execute(cls, client, args):
136-
mq_client = get_mq_client(args['<account_id>'], cls.env)
187+
manager = MessagingManager(client)
188+
mq_client = get_mq_client(manager, args['<account_id>'], cls.env)
137189

138190
# list
139191
if args['list']:
140-
queues = mq_client.queues()['items']
192+
queues = mq_client.get_queues()['items']
141193

142194
t = Table([
143195
'name', 'message_count', 'visible_message_count'
@@ -151,7 +203,7 @@ def execute(cls, client, args):
151203
return t
152204
# detail
153205
elif args['detail']:
154-
queue = mq_client.queue(args['<queue_name>']).detail()
206+
queue = mq_client.get_queue(args['<queue_name>'])
155207
return queue_table(queue)
156208
# create
157209
elif args['create'] or args['modify']:
@@ -169,10 +221,12 @@ def execute(cls, client, args):
169221
# delete
170222
elif args['delete']:
171223
if args['<message_id>']:
172-
messages = mq_client.queue(args['<queue_name>']).message(
173-
args['<message_id>']).delete()
224+
messages = mq_client.delete_message(
225+
args['<queue_name>'],
226+
['<message_id>'])
174227
else:
175-
mq_client.queue(args['<queue_name>']).delete(
228+
mq_client.delete_queue(
229+
args['<queue_name>'],
176230
args.get('--force'))
177231
# push message
178232
elif args['push']:
@@ -183,21 +237,28 @@ def execute(cls, client, args):
183237
else:
184238
body = sys.stdin.read()
185239
return message_table(
186-
mq_client.queue(args['<queue_name>']).push(body))
240+
mq_client.push_queue_message(args['<queue_name>'], body))
187241
# pop message
188242
elif args['pop']:
189-
messages = mq_client.queue(args['<queue_name>']).pop(
243+
messages = mq_client.pop_message(
244+
args['<queue_name>'],
190245
args.get('--count') or 1)
191246
formatted_messages = []
192247
for message in messages['items']:
193248
formatted_messages.append(message_table(message))
249+
250+
if args.get('--delete-after'):
251+
for message in messages['items']:
252+
mq_client.delete_message(
253+
args['<queue_name>'],
254+
message['id'])
194255
return formatted_messages
195256
else:
196257
raise CLIAbort('Invalid command')
197258

198259

199260
class Topic(CLIRunnable):
200-
"""
261+
__doc__ = """
201262
usage: sl messaging topic list <account_id> [options]
202263
sl messaging topic detail <account_id> <topic_name> [options]
203264
sl messaging topic create <account_id> <topic_name> [options]
@@ -217,40 +278,42 @@ class Topic(CLIRunnable):
217278
Topic Delete Options:
218279
--force Flag to force the deletion of the topic even when there are subscriptions
219280
220-
"""
281+
""" + COMMON_MESSAGING_ARGS
221282
action = 'topic'
222283

223284
@classmethod
224285
def execute(cls, client, args):
225-
mq_client = get_mq_client(args['<account_id>'], cls.env)
286+
manager = MessagingManager(client)
287+
mq_client = get_mq_client(manager, args['<account_id>'], cls.env)
226288

227289
# list
228290
if args['list']:
229-
topics = mq_client.topics()['items']
291+
topics = mq_client.get_topics()['items']
230292

231293
t = Table(['name'])
232294
for topic in topics:
233295
t.add_row([topic['name']])
234296
return t
235297
# detail
236298
elif args['detail']:
237-
topic = mq_client.topic(args['<topic_name>']).detail()
238-
subscriptions = mq_client.topic(args['<topic_name>']).subscriptions()
299+
topic = mq_client.get_topic(args['<topic_name>'])
300+
subscriptions = mq_client.get_subscriptions(args['<topic_name>'])
239301
tables = []
240302
for sub in subscriptions['items']:
241303
tables.append(subscription_table(sub))
242304
return [topic_table(topic), tables]
243305
# create
244306
elif args['create']:
245307
if args['--subscription']:
246-
topic = mq_client.topic(args['<topic_name>'])
247308
if args['--type'] == 'queue':
248-
subscription = topic.create_subscription(
309+
subscription = mq_client.create_subscription(
310+
args['<topic_name>'],
249311
'queue',
250312
queue_name=args['--queue-name'],
251313
)
252314
elif args['--type'] == 'http':
253-
subscription = topic.create_subscription(
315+
subscription = mq_client.create_subscription(
316+
args['<topic_name>'],
254317
'http',
255318
method=args['--http-method'] or 'GET',
256319
url=args['--http-url'],
@@ -275,10 +338,12 @@ def execute(cls, client, args):
275338
# delete
276339
elif args['delete']:
277340
if args['<subscription_id>']:
278-
messages = mq_client.topic(args['<topic_name>']).subscription(
279-
args['<subscription_id>']).delete()
341+
mq_client.delete_subscription(
342+
args['<topic_name>'],
343+
args['<subscription_id>'])
280344
else:
281-
mq_client.topic(args['<topic_name>']).delete(
345+
mq_client.delete_topic(
346+
args['<topic_name>'],
282347
args.get('--force'))
283348
# push message
284349
elif args['push']:
@@ -289,14 +354,6 @@ def execute(cls, client, args):
289354
else:
290355
body = sys.stdin.read()
291356
return message_table(
292-
mq_client.topic(args['<topic_name>']).push(body))
293-
# pop message
294-
elif args['pop']:
295-
messages = mq_client.topic(args['<topic_name>']).pop(
296-
args.get('--count') or 1)
297-
formatted_messages = []
298-
for message in messages['items']:
299-
formatted_messages.append(message_table(message))
300-
return formatted_messages
357+
mq_client.push_topic_message(args['<topic_name>'], body))
301358
else:
302359
raise CLIAbort('Invalid command')

SoftLayer/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ class SoftLayerError(StandardError):
1212
" The base SoftLayer error. "
1313

1414

15+
class Unauthenticated(StandardError):
16+
" Unauthenticated "
17+
18+
1519
class SoftLayerAPIError(SoftLayerError):
1620
""" SoftLayerAPIError is an exception raised whenever an error is returned
1721
from the API.

SoftLayer/managers/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
from SoftLayer.managers.dns import DNSManager
1313
from SoftLayer.managers.firewall import FirewallManager
1414
from SoftLayer.managers.hardware import HardwareManager
15+
from SoftLayer.managers.messaging import MessagingManager
1516
from SoftLayer.managers.metadata import MetadataManager
1617
from SoftLayer.managers.ssl import SSLManager
1718

1819
__all__ = ['CCIManager', 'DNSManager', 'FirewallManager', 'HardwareManager',
19-
'MetadataManager', 'SSLManager']
20+
'MessagingManager', 'MetadataManager', 'SSLManager']

0 commit comments

Comments
 (0)