Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Remove session concept #7

Merged
merged 15 commits into from about 1 year ago

2 participants

Tomaz Muraus Gary Dusbabek
Tomaz Muraus
Kami commented March 28, 2013

No description provided.

Gary Dusbabek
Collaborator

Lots of changes, so I didn't give it a close review. Nothing glaring stood out, so +1 on that basis.

Tomaz Muraus Kami merged commit 0fec294 into from March 28, 2013
Tomaz Muraus Kami closed this March 28, 2013
Tomaz Muraus Kami deleted the branch March 28, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

Showing 22 changed files with 140 additions and 495 deletions. Show diff stats Hide diff stats

  1. 2  .gitignore
  2. 171  README.md
  3. 2  setup.py
  4. 132  txServiceRegistry/client.py
  5. 4  txServiceRegistry/test/fixtures/request/services-post.json
  6. 6  txServiceRegistry/test/fixtures/request/sessions-post.json
  7. 18  txServiceRegistry/test/fixtures/response/configuration-api-get.json
  8. 6  txServiceRegistry/test/fixtures/response/events-get.json
  9. 5  txServiceRegistry/test/fixtures/response/services-dfw1-db1-get.json
  10. 0  txServiceRegistry/test/fixtures/response/{sessions-post.json → services-dfw1-db1-heartbeat-post.json}
  11. 5  txServiceRegistry/test/fixtures/response/services-get-limit-1-page-1.json
  12. 5  txServiceRegistry/test/fixtures/response/services-get-with-marker-page-2.json
  13. 8  txServiceRegistry/test/fixtures/response/services-get.json
  14. 4  txServiceRegistry/test/fixtures/response/{sessions-not-found-get.json → services-not-found-get.json}
  15. 0  txServiceRegistry/test/fixtures/response/{sessions-sessionId-heartbeat-post.json → services-post.json}
  16. 5  txServiceRegistry/test/fixtures/response/services-tag-db-get.json
  17. 18  txServiceRegistry/test/fixtures/response/sessions-get.json
  18. 8  txServiceRegistry/test/fixtures/response/sessions-sessionId-get.json
  19. 42  txServiceRegistry/test/fixtures/response/views-overview-get.json
  20. 28  txServiceRegistry/test/mock_http_server.py
  21. 92  txServiceRegistry/test/test_client.py
  22. 74  txServiceRegistry/test/utils.py
2  .gitignore
@@ -2,3 +2,5 @@
2 2
 *.pyc
3 3
 _trial_temp
4 4
 mock_api_server.log
  5
+dist/
  6
+txServiceRegistry.egg-info
171  README.md
Source Rendered
@@ -18,175 +18,10 @@ RACKSPACE_KEY = 'api key'
18 18
 
19 19
 client = Client(RACKSPACE_USERNAME, RACKSPACE_KEY)
20 20
 
  21
+# Do something
  22
+reactor.run()
  23
+
21 24
 def resultCallback(result):
22 25
     print result
23 26
     reactor.stop()
24 27
 ```
25  
-
26  
-## Sessions
27  
-
28  
-Create a session with a heartbeat timeout of 10:
29  
-
30  
-```Python
31  
-# Optional metadata (must contain string keys and values, up to 255 chars)
32  
-options = {'key': 'value'}
33  
-heartbeatTimeout = 10
34  
-
35  
-d = client.sessions.create(heartbeatTimeout, options)
36  
-d.addCallback(resultCallback)
37  
-```
38  
-
39  
-List sessions:
40  
-
41  
-```Python
42  
-d = client.sessions.list()
43  
-d.addCallback(resultCallback)
44  
-```
45  
-
46  
-Get session:
47  
-
48  
-```Python
49  
-sessionId = 'seFoo'
50  
-
51  
-d = client.sessions.get(sessionId)
52  
-d.addCallback(resultCallback)
53  
-```
54  
-
55  
-Heartbeat a session:
56  
-
57  
-```Python
58  
-sessionId = 'seFoo'
59  
-token = 'token'
60  
-
61  
-d = client.sessions.heartbeat(sessionId, token)
62  
-d.addCallback(resultCallback)
63  
-```
64  
-
65  
-Update existing session:
66  
-
67  
-```Python
68  
-sessionId = 'seFoo'
69  
-payload = {'heartbeat_timeout': 15}
70  
-
71  
-d = client.sessions.update(sessionId, payload)
72  
-d.addCallback(resultCallback)
73  
-```
74  
-
75  
-## Events
76  
-
77  
-List events:
78  
-
79  
-```Python
80  
-marker = 'last-seen-token'
81  
-
82  
-d = client.events.list(marker)
83  
-d.addCallback(resultCallback)
84  
-```
85  
-
86  
-## Services
87  
-
88  
-List services:
89  
-
90  
-```Python
91  
-
92  
-d = client.services.list()
93  
-d.addCallback(resultCallback)
94  
-```
95  
-
96  
-List services for a specific tag:
97  
-
98  
-```Python
99  
-tag = 'tag'
100  
-
101  
-d = client.services.listForTag(tag)
102  
-d.addCallback(resultCallback)
103  
-```
104  
-
105  
-Get service by ID:
106  
-
107  
-```Python
108  
-serviceId = 'messenger1'
109  
-
110  
-d = client.services.get(serviceId)
111  
-d.addCallback(resultCallback)
112  
-```
113  
-
114  
-Create a new service:
115  
-
116  
-```Python
117  
-sessionId = 'sessionId'
118  
-serviceId = 'messenger1'
119  
-payload = {
120  
-    'tags': ['messenger', 'stats'],
121  
-    'metadata': {'someKey': 'someValue', 'anotherKey': 'anotherValue'}
122  
-}
123  
-
124  
-d = client.services.register(sessionId, serviceId, payload)
125  
-d.addCallback(resultCallback)
126  
-```
127  
-
128  
-Update existing service:
129  
-
130  
-```Python
131  
-serviceId = 'messenger1'
132  
-payload = {
133  
-    'tags': ['tag1', 'tag2'],
134  
-    'metadata': {'aKey': 'aValue'}
135  
-}
136  
-
137  
-d = client.services.update(serviceId, payload)
138  
-d.addCallback(resultCallback)
139  
-```
140  
-
141  
-## Configuration
142  
-
143  
-List configuration values:
144  
-
145  
-```Python
146  
-
147  
-d = client.configuration.list()
148  
-d.addCallback(resultCallback)
149  
-```
150  
-
151  
-Get configuration value by id:
152  
-
153  
-```Python
154  
-configurationId = 'configId'
155  
-
156  
-d = client.configuration.get(configurationId)
157  
-d.addCallback(resultCallback)
158  
-```
159  
-
160  
-Update configuration value:
161  
-
162  
-```Python
163  
-configurationId = 'configId'
164  
-value = 'new-value'
165  
-
166  
-d = client.configuration.set(configurationId, value)
167  
-d.addCallback(resultCallback)
168  
-```
169  
-
170  
-Delete configuration value:
171  
-
172  
-```Python
173  
-configurationId = 'configId'
174  
-
175  
-d = client.configuration.remove(configurationId)
176  
-d.addCallback(resultCallback)
177  
-```
178  
-
179  
-## Accounts
180  
-
181  
-Get account limits:
182  
-
183  
-```Python
184  
-d = client.account.getLimits()
185  
-d.addCallback(resultCallback)
186  
-```
187  
-
188  
-Also, make sure to call:
189  
-
190  
-```Python
191  
-reactor.run()
192  
-```
2  setup.py
@@ -100,7 +100,7 @@ def run(self):
100 100
 
101 101
 setup(
102 102
     name='txServiceRegistry',
103  
-    version='0.1.3',
  103
+    version='0.2.0',
104 104
     description='A Twisted Python client for Rackspace Service Registry.',
105 105
     author='Rackspace Hosting, Inc.',
106 106
     author_email='sr@rackspace.com',
132  txServiceRegistry/client.py
@@ -47,20 +47,16 @@ class ResponseReceiver(Protocol):
47 47
     as it arrives.
48 48
     When the body has been completely delivered, connectionLost is called.
49 49
     """
50  
-    def __init__(self, finished, idFromUrl=None, heartbeater=None):
  50
+    def __init__(self, finished, heartbeater=None):
51 51
         """
52 52
         @param finished: Deferred to callback with result in connectionLost
53 53
         @type finished: L{Deferred}
54  
-        @param idFromUrl: Optional session or service ID that was parsed out
55  
-        of the location header.
56  
-        @type idFromUrl: C{str}
57 54
         @param heartbeater: Optional HeartBeater object created when a
58 55
         session is created.
59 56
         @type heartbeater: L{HeartBeater}
60 57
         """
61 58
         self.finished = finished
62 59
         self.remaining = StringIO()
63  
-        self.idFromUrl = idFromUrl
64 60
         self.heartbeater = heartbeater
65 61
 
66 62
     def dataReceived(self, receivedBytes):
@@ -79,29 +75,19 @@ def connectionLost(self, reason):
79 75
         a twisted.web.http.PotentialDataLoss exception.
80 76
         """
81 77
         self.remaining.reset()
82  
-        # When creating a session, the token is returned in the body, and the
83  
-        # session ID is in the location header URL. When creating a service,
84  
-        # the body is empty, and the service ID is in the location header URL.
85  
-        if self.idFromUrl:
86  
-            result = None
87  
-            if self.remaining.getvalue():
88  
-                result = json.load(self.remaining)
89  
-
90  
-            returnTuple = (result, self.idFromUrl)
91  
-            if self.heartbeater:
92  
-                self.heartbeater.nextToken = result['token']
93  
-                returnTuple = returnTuple + (self.heartbeater,)
94  
-
95  
-            # Return just service ID if result is None
96  
-            if result is None:
97  
-                self.finished.callback(self.idFromUrl)
98  
-            else:
99  
-                self.finished.callback(returnTuple)
100 78
 
  79
+        try:
  80
+            result = json.load(self.remaining)
  81
+        except Exception, e:
  82
+            self.finished.errback(e)
101 83
             return
102 84
 
103  
-        result = json.load(self.remaining)
104  
-        self.finished.callback(result)
  85
+        returnValue = result
  86
+        if self.heartbeater:
  87
+            self.heartbeater.nextToken = result['token']
  88
+            returnValue = (result, self.heartbeater)
  89
+
  90
+        self.finished.callback(returnValue)
105 91
 
106 92
 
107 93
 class BaseClient(object):
@@ -147,23 +133,13 @@ def cbRequest(self,
147 133
                                     heartbeater,
148 134
                                     retry_count)
149 135
             finished = Deferred()
150  
-            idFromUrl = None
151 136
             # If response has no body, callback with True
152 137
             if response.code == httplib.NO_CONTENT:
153 138
                 finished.callback(True)
154 139
 
155 140
                 return finished
156 141
 
157  
-            # If response code is 201, extract service or session id
158  
-            # from the location
159  
-            if response.code == httplib.CREATED:
160  
-                locationHeader = response.headers.getRawHeaders('location')[0]
161  
-                idFromUrl = self.getIdFromUrl(locationHeader)
162  
-                if 'sessions' in locationHeader:
163  
-                    heartbeater.sessionId = idFromUrl
164  
-
165 142
             response.deliverBody(ResponseReceiver(finished,
166  
-                                                  idFromUrl,
167 143
                                                   heartbeater))
168 144
 
169 145
             return finished
@@ -218,50 +194,6 @@ def _request(authHeaders, options, payload, heartbeater, retry_count):
218 194
         return d
219 195
 
220 196
 
221  
-class SessionsClient(BaseClient):
222  
-    def __init__(self, agent, baseUrl):
223  
-        super(SessionsClient, self).__init__(agent, baseUrl)
224  
-        self.agent = agent
225  
-        self.baseUrl = baseUrl
226  
-        self.sessionsPath = '/sessions'
227  
-
228  
-    def list(self, marker=None, limit=None):
229  
-        path = self.sessionsPath
230  
-        options = self._get_options_object(marker, limit)
231  
-
232  
-        return self.request('GET', path, options=options)
233  
-
234  
-    def get(self, sessionId):
235  
-        path = '%s/%s' % (self.sessionsPath, sessionId)
236  
-
237  
-        return self.request('GET', path)
238  
-
239  
-    def create(self, heartbeatTimeout, payload=None):
240  
-        path = self.sessionsPath
241  
-        payload = deepcopy(payload) if payload else {}
242  
-        payload['heartbeat_timeout'] = heartbeatTimeout
243  
-        heartbeater = HeartBeater(self.agent,
244  
-                                  self.baseUrl,
245  
-                                  None,
246  
-                                  heartbeatTimeout)
247  
-
248  
-        return self.request('POST',
249  
-                            path,
250  
-                            payload=payload,
251  
-                            heartbeater=heartbeater)
252  
-
253  
-    def heartbeat(self, sessionId, token):
254  
-        path = '%s/%s/heartbeat' % (self.sessionsPath, sessionId)
255  
-        payload = {'token': token}
256  
-
257  
-        return self.request('POST', path, payload=payload)
258  
-
259  
-    def update(self, sessionId, payload):
260  
-        path = '%s/%s' % (self.sessionsPath, sessionId)
261  
-
262  
-        return self.request('PUT', path, payload=payload)
263  
-
264  
-
265 197
 class EventsClient(BaseClient):
266 198
     def __init__(self, agent, baseUrl):
267 199
         super(EventsClient, self).__init__(agent, baseUrl)
@@ -294,12 +226,23 @@ def get(self, serviceId):
294 226
 
295 227
         return self.request('GET', path)
296 228
 
297  
-    def create(self, sessionId, serviceId, payload=None):
  229
+    def create(self, serviceId, heartbeatTimeout, payload=None):
298 230
         payload = deepcopy(payload) if payload else {}
299  
-        payload['session_id'] = sessionId
300 231
         payload['id'] = serviceId
  232
+        payload['heartbeat_timeout'] = heartbeatTimeout
  233
+        heartbeater = HeartBeater(self.agent,
  234
+                                  self.baseUrl,
  235
+                                  None,
  236
+                                  heartbeatTimeout)
  237
+
  238
+        return self.request('POST', self.servicesPath, payload=payload,
  239
+                            heartbeater=heartbeater)
301 240
 
302  
-        return self.request('POST', self.servicesPath, payload=payload)
  241
+    def heartbeat(self, serviceId, token):
  242
+        path = '%s/%s/heartbeat' % (self.servicesPath, serviceId)
  243
+        payload = {'token': token}
  244
+
  245
+        return self.request('POST', path, payload=payload)
303 246
 
304 247
     def update(self, serviceId, payload):
305 248
         path = '%s/%s' % (self.servicesPath, serviceId)
@@ -311,19 +254,19 @@ def remove(self, serviceId):
311 254
 
312 255
         return self.request('DELETE', path)
313 256
 
314  
-    def register(self, sessionId, serviceId, payload=None, retryDelay=2):
  257
+    def register(self, serviceId, heartbeatTimeout, payload=None,
  258
+                 retryDelay=2):
315 259
         retryCount = MAX_HEARTBEAT_TIMEOUT / retryDelay
316 260
         success = False
317 261
         retryCounter = 0
318 262
         registerResult = Deferred()
319 263
         lastErr = None
320 264
 
321  
-        def doRegister(sessionId, serviceId, retryCounter, success, lastErr):
  265
+        def doRegister(serviceId, heartbeatTimeout, retryCounter,
  266
+                       success, lastErr, result=None):
322 267
             if success and (retryCounter < retryCount):
323  
-                registerResult.callback(serviceId)
324  
-
  268
+                registerResult.callback(result)
325 269
                 return registerResult
326  
-
327 270
             elif (not success) and (retryCounter == retryCount):
328 271
                 registerResult.errback(lastErr)
329 272
 
@@ -337,8 +280,9 @@ def cbCreate(result, retryCounter, success):
337 280
                     lastErr = result
338 281
                     if result['type'] == 'serviceWithThisIdExists':
339 282
                         retryCounter += 1
340  
-                        reactor.callLater(retryDelay, doRegister, sessionId,
341  
-                                          serviceId, retryCounter, success,
  283
+                        reactor.callLater(retryDelay, doRegister,
  284
+                                          serviceId, heartbeatTimeout,
  285
+                                          retryCounter, success,
342 286
                                           lastErr)
343 287
 
344 288
                         return registerResult
@@ -347,15 +291,16 @@ def cbCreate(result, retryCounter, success):
347 291
 
348 292
                         return registerResult
349 293
                 else:
350  
-                    return doRegister(sessionId, serviceId, retryCounter,
351  
-                                      True, None)
  294
+                    return doRegister(serviceId, heartbeatTimeout,
  295
+                                      retryCounter, True, None, result)
352 296
 
353  
-            d = self.create(sessionId, serviceId, payload)
  297
+            d = self.create(serviceId, heartbeatTimeout, payload)
354 298
             d.addCallback(cbCreate, retryCounter, success)
355 299
 
356 300
             return d
357 301
 
358  
-        return doRegister(sessionId, serviceId, retryCounter, success, lastErr)
  302
+        return doRegister(serviceId, heartbeatTimeout, retryCounter, success,
  303
+                          lastErr)
359 304
 
360 305
 
361 306
 class ConfigurationClient(BaseClient):
@@ -488,7 +433,6 @@ def __init__(self, username, apiKey, region='us', baseUrl=DEFAULT_API_URL,
488 433
 
489 434
         self.agent = KeystoneAgent(agent, authUrl, (username, apiKey))
490 435
         self.baseUrl = baseUrl
491  
-        self.sessions = SessionsClient(self.agent, self.baseUrl)
492 436
         self.events = EventsClient(self.agent, self.baseUrl)
493 437
         self.services = ServicesClient(self.agent, self.baseUrl)
494 438
         self.configuration = ConfigurationClient(self.agent, self.baseUrl)
4  txServiceRegistry/test/fixtures/request/services-post.json
@@ -10,5 +10,5 @@
10 10
         "version": "5.5.24-0ubuntu0.12.04.1 (Ubuntu)"
11 11
     },
12 12
     "id": "dfw1-db1",
13  
-    "session_id": "sessionId"
14  
-}
  13
+    "heartbeat_timeout": 30
  14
+}
6  txServiceRegistry/test/fixtures/request/sessions-post.json
... ...
@@ -1,6 +0,0 @@
1  
-{
2  
-    "metadata": {
3  
-        "region": "dfw"
4  
-    },
5  
-    "heartbeat_timeout": 30
6  
-}
18  txServiceRegistry/test/fixtures/response/configuration-api-get.json
... ...
@@ -0,0 +1,18 @@
  1
+{
  2
+    "values": [
  3
+        {
  4
+            "id": "/api/key-1",
  5
+            "value": "test value 123456"
  6
+        },
  7
+        {
  8
+            "id": "/api/key-2",
  9
+            "value": "test value 23456"
  10
+        }
  11
+    ],
  12
+    "metadata": {
  13
+        "count": 2,
  14
+        "limit": 100,
  15
+        "marker": null,
  16
+        "next_href": null
  17
+    }
  18
+}
6  txServiceRegistry/test/fixtures/response/events-get.json
... ...
@@ -1,4 +1,4 @@
1  
-{
  1
+
2 2
     "values": [
3 3
         {
4 4
             "id": "6bc8d050-f86a-11e1-a89e-ca2ffe480b20",
@@ -6,7 +6,6 @@
6 6
             "type": "service.join",
7 7
             "payload": {
8 8
                 "id": "dfw1-api",
9  
-                "session_id": "sessionId",
10 9
                 "tags": [],
11 10
                 "metadata": {}
12 11
             }
@@ -15,7 +14,6 @@
15 14
             "type": "service.join",
16 15
             "payload": {
17 16
                 "id": "dfw1-db1",
18  
-                "session_id": "sessionId",
19 17
                 "tags": [
20 18
                     "db",
21 19
                     "mysql"
@@ -43,4 +41,4 @@
43 41
         "marker": null,
44 42
         "next_href": null
45 43
     }
46  
-}
  44
+}
5  txServiceRegistry/test/fixtures/response/services-dfw1-db1-get.json
... ...
@@ -1,6 +1,7 @@
1 1
 {
2 2
     "id": "dfw1-db1",
3  
-    "session_id": "sessionId",
  3
+    "heartbeat_timeout": 30,
  4
+    "last_seen": 1362900438,
4 5
     "tags": [
5 6
         "db",
6 7
         "mysql"
@@ -11,4 +12,4 @@
11 12
         "ip": "127.0.0.1",
12 13
         "version": "5.5.24-0ubuntu0.12.04.1 (Ubuntu)"
13 14
     }
14  
-}
  15
+}
0  ...egistry/test/fixtures/response/sessions-post.json → ...es/response/services-dfw1-db1-heartbeat-post.json
File renamed without changes
5  txServiceRegistry/test/fixtures/response/services-get-limit-1-page-1.json
@@ -2,7 +2,8 @@
2 2
     "values": [
3 3
         {
4 4
             "id": "dfw1-api",
5  
-            "session_id": "seOne",
  5
+            "heartbeat_timeout": 30,
  6
+            "last_seen": 1362900438,
6 7
             "tags": [],
7 8
             "metadata": {}
8 9
         }
@@ -14,4 +15,4 @@
14 15
         "next_marker": "dfw1-db1",
15 16
         "next_href": "https://todo.api.rackspacecloud.com/v1.0/7777/services?limit=1&marker=dfw1-db1"
16 17
     }
17  
-}
  18
+}
5  txServiceRegistry/test/fixtures/response/services-get-with-marker-page-2.json
@@ -2,7 +2,8 @@
2 2
     "values": [
3 3
         {
4 4
             "id": "dfw1-db1",
5  
-            "session_id": "seOne",
  5
+            "heartbeat_timeout": 30,
  6
+            "last_seen": 1362900438,
6 7
             "tags": [
7 8
                 "db",
8 9
                 "mysql"
@@ -21,4 +22,4 @@
21 22
         "marker": "dfw1-db1",
22 23
         "next_href": null
23 24
     }
24  
-}
  25
+}
8  txServiceRegistry/test/fixtures/response/services-get.json
@@ -2,13 +2,15 @@
2 2
     "values": [
3 3
         {
4 4
             "id": "dfw1-api",
5  
-            "session_id": "sessionId",
  5
+            "heartbeat_timeout": 30,
  6
+            "last_seen": 1362900438,
6 7
             "tags": [],
7 8
             "metadata": {}
8 9
         },
9 10
         {
10 11
             "id": "dfw1-db1",
11  
-            "session_id": "sessionId",
  12
+            "heartbeat_timeout": 30,
  13
+            "last_seen": 1362900438,
12 14
             "tags": [
13 15
                 "db",
14 16
                 "mysql"
@@ -27,4 +29,4 @@
27 29
         "marker": null,
28 30
         "next_href": null
29 31
     }
30  
-}
  32
+}
4  ...est/fixtures/response/sessions-not-found-get.json → ...est/fixtures/response/services-not-found-get.json
@@ -2,6 +2,6 @@
2 2
     "type": "notFoundError",
3 3
     "code": 404,
4 4
     "message": "object does not exist",
5  
-    "details": "Object \"Session\" with key \"seNotFound\" does not exist",
  5
+    "details": "Object \"Service\" with key \"my-service-1\" does not exist",
6 6
     "txnId": ".rh-qyek.h-farscape.r-q3i5psGp.c-3.ts-1347320188220.v-0.1"
7  
-}
  7
+}
0  ...s/response/sessions-sessionId-heartbeat-post.json → ...egistry/test/fixtures/response/services-post.json
File renamed without changes
5  txServiceRegistry/test/fixtures/response/services-tag-db-get.json
@@ -2,7 +2,8 @@
2 2
     "values": [
3 3
         {
4 4
             "id": "dfw1-db1",
5  
-            "session_id": "sessionId",
  5
+            "heartbeat_timeout": 30,
  6
+            "last_seen": 1362900438,
6 7
             "tags": [
7 8
                 "db",
8 9
                 "mysql"
@@ -21,4 +22,4 @@
21 22
         "marker": null,
22 23
         "next_href": null
23 24
     }
24  
-}
  25
+}
18  txServiceRegistry/test/fixtures/response/sessions-get.json
... ...
@@ -1,18 +0,0 @@
1  
-{
2  
-    "values": [
3  
-        {
4  
-            "id": "sessionId",
5  
-            "metadata": {
6  
-                "region": "dfw"
7  
-            },
8  
-            "heartbeat_timeout": 30,
9  
-            "last_seen": null
10  
-        }
11  
-    ],
12  
-    "metadata": {
13  
-        "count": 1,
14  
-        "limit": 100,
15  
-        "marker": null,
16  
-        "next_href": null
17  
-    }
18  
-}
8  txServiceRegistry/test/fixtures/response/sessions-sessionId-get.json
... ...
@@ -1,8 +0,0 @@
1  
-{
2  
-    "id": "sessionId",
3  
-    "metadata": {
4  
-        "region": "dfw"
5  
-    },
6  
-    "heartbeat_timeout": 30,
7  
-    "last_seen": null
8  
-}
42  txServiceRegistry/test/fixtures/response/views-overview-get.json
... ...
@@ -1,42 +0,0 @@
1  
-{
2  
-    "values": [
3  
-        {
4  
-            "session": {
5  
-                "id": "seId0",
6  
-                "metadata": {
7  
-                    "region": "dfw"
8  
-                },
9  
-                "heartbeat_timeout": 30,
10  
-                "last_seen": null
11  
-            },
12  
-            "services": [
13  
-                {
14  
-                    "id": "dfw1-api",
15  
-                    "session_id": "seId0",
16  
-                    "tags": [],
17  
-                    "metadata": {}
18  
-                },
19  
-                {
20  
-                    "id": "dfw1-db1",
21  
-                    "session_id": "seId0",
22  
-                    "tags": [
23  
-                        "db",
24  
-                        "mysql"
25  
-                    ],
26  
-                    "metadata": {
27  
-                        "region": "dfw",
28  
-                        "port": "3306",
29  
-                        "ip": "127.0.0.1",
30  
-                        "version": "5.5.24-0ubuntu0.12.04.1 (Ubuntu)"
31  
-                    }
32  
-                }
33  
-            ]
34  
-        }
35  
-    ],
36  
-    "metadata": {
37  
-        "count": 1,
38  
-        "limit": 100,
39  
-        "marker": null,
40  
-        "next_href": null
41  
-    }
42  
-}
28  txServiceRegistry/test/mock_http_server.py
@@ -25,13 +25,13 @@
25 25
 signature = None
26 26
 
27 27
 HTTP_GET_PATHS = {
28  
-    '/sessions': {'fixture_path': 'sessions-get.json'},
29  
-    '/sessions/sessionId': {'fixture_path': 'sessions-sessionId-get.json'},
30 28
     '/limits': {'fixture_path': 'limits-get.json'},
31 29
     '/events': {'fixture_path': 'events-get.json'},
32 30
     '/configuration': {'fixture_path': 'configuration-get.json'},
33 31
     '/configuration/configId':
34 32
     {'fixture_path': 'configuration-configId-get.json'},
  33
+    '/configuration/api/':
  34
+    {'fixture_path': 'configuration-api-get.json'},
35 35
     '/services': {'fixture_path': 'services-get.json'},
36 36
     '/services/dfw1-db1':
37 37
     {'fixture_path': 'services-dfw1-db1-get.json'},
@@ -39,14 +39,12 @@
39 39
 }
40 40
 
41 41
 HTTP_POST_PATHS = {
42  
-    '/sessions':
43  
-    {'fixture_path': 'sessions-post.json',
44  
-     'headers': {'Location': '127.0.0.1/v1.0/7777/sessions/sessionId'}},
45  
-    '/sessions/sessionId/heartbeat':
46  
-    {'fixture_path': 'sessions-sessionId-heartbeat-post.json',
47  
-     'status_code': 200},
48 42
     '/services':
49  
-    {'headers': {'Location': '127.0.0.1/v1.0/7777/services/dfw1-db1'}}
  43
+    {'fixture_path': 'services-post.json',
  44
+     'headers': {'Location': '127.0.0.1/v1.0/7777/services/dfw1-db1'}},
  45
+    '/services/dfw1-db1/heartbeat':
  46
+    {'fixture_path': 'services-dfw1-db1-heartbeat-post.json',
  47
+     'status_code': 200}
50 48
 }
51 49
 
52 50
 usage = 'usage: %prog --port=<port> --fixtures-dir=<fixtures directory>'
@@ -55,8 +53,7 @@
55 53
                   help='Port to listen on', metavar='PORT')
56 54
 parser.add_option("--fixtures-dir", dest='fixtures_dir',
57 55
                   default='fixtures/response/',
58  
-                  help='The folder in which JSON response fixtures'
59  
-                       ' for the tests live')
  56
+                  help='The folder in which JSON fixtures for the tests live')
60 57
 
61 58
 (options, args) = parser.parse_args()
62 59
 
@@ -90,11 +87,7 @@ def do_POST(self):
90 87
         return self._setup_response(HTTP_POST_PATHS, 201)
91 88
 
92 89
     def do_PUT(self):
93  
-        if 'sessions' in self.path:
94  
-            headers = \
95  
-                {'Location': '127.0.0.1/v1.0/7777/sessions/sessionId'}
96  
-            return self._end(status_code=204, headers=headers)
97  
-        elif 'services' in self.path:
  90
+        if 'services' in self.path:
98 91
             headers = \
99 92
                 {'Location': '127.0.0.1/v1.0/7777/services/dfw1-db1'}
100 93
             return self._end(status_code=204, headers=headers)
@@ -104,12 +97,15 @@ def do_DELETE(self):
104 97
 
105 98
     def _end(self, status_code=200, headers=None, body=''):
106 99
         print 'Sending response: status_code=%s, body=%s' % (status_code, body)
  100
+
107 101
         self.send_response(status_code)
108 102
         self.send_header('Content-Type', 'application/json')
109 103
         self.send_header('Content-Length', str(len(body)))
  104
+
110 105
         if headers:
111 106
             for key, value in headers.iteritems():
112 107
                 self.send_header(key, value)
  108
+
113 109
         self.end_headers()
114 110
         self.wfile.write(body)
115 111
 
92  txServiceRegistry/test/test_client.py
@@ -55,54 +55,49 @@ def limits_assert(result):
55 55
 
56 56
         return d
57 57
 
58  
-    def test_create_session(self):
59  
-        def session_assert(result):
  58
+    def test_create_service(self):
  59
+        def service_assert(result):
60 60
             response_body = {'token': TOKENS[0]}
61 61
             self.assertEqual(result[0], response_body)
62  
-            self.assertEqual(result[1], 'sessionId')
63  
-            self.assertTrue(isinstance(result[2], HeartBeater))
64  
-            self.assertEqual(result[2].heartbeatInterval, 12.0)
65  
-            self.assertEqual(result[2].nextToken, TOKENS[0])
66  
-
67  
-        d = self.client.sessions.create(15)
68  
-        d.addCallback(session_assert)
  62
+            self.assertTrue(isinstance(result[1], HeartBeater))
  63
+            self.assertEqual(result[1].heartbeatInterval, 12.0)
  64
+            self.assertEqual(result[1].nextToken, TOKENS[0])
69 65
 
70  
-        return d
71  
-
72  
-    def test_heartbeat_session(self):
73  
-        def heartbeat_assert(result):
74  
-            heartbeat_response = {'token': TOKENS[0]}
75  
-            self.assertEqual(result, heartbeat_response)
76  
-
77  
-        d = self.client.sessions.heartbeat('sessionId', 'someToken')
78  
-        d.addCallback(heartbeat_assert)
  66
+        d = self.client.services.create('dfw1-db1', 15)
  67
+        d.addCallback(service_assert)
79 68
 
80 69
         return d
81 70
 
82  
-    def test_create_service(self):
  71
+    def test_register_service(self):
83 72
         def service_assert(result):
84  
-            self.assertEqual(result, 'dfw1-db1')
  73
+            response_body = {'token': TOKENS[0]}
  74
+            self.assertEqual(result[0], response_body)
  75
+            self.assertTrue(isinstance(result[1], HeartBeater))
  76
+            self.assertEqual(result[1].heartbeatInterval, 12.0)
  77
+            self.assertEqual(result[1].nextToken, TOKENS[0])
85 78
 
86  
-        d = self.client.services.create('sessionId', 'dfw1-db1')
  79
+        d = self.client.services.register('dfw1-db1', 15)
87 80
         d.addCallback(service_assert)
88 81
 
89 82
         return d
90 83
 
91  
-    def test_register_service(self):
92  
-        def service_assert(result):
93  
-            self.assertEqual(result, 'dfw1-db1')
  84
+    def test_heartbeat_service(self):
  85
+        def heartbeat_assert(result):
  86
+            heartbeat_response = {'token': TOKENS[0]}
  87
+            self.assertEqual(result, heartbeat_response)
94 88
 
95  
-        d = self.client.services.register('sessionId', 'dfw1-db1')
96  
-        d.addCallback(service_assert)
  89
+        d = self.client.services.heartbeat('dfw1-db1', 'someToken')
  90
+        d.addCallback(heartbeat_assert)
97 91
 
98 92
         return d
99 93
 
100 94
     def test_get_service(self):
101 95
         def service_assert(result):
102 96
             self.assertEqual(result['id'], 'dfw1-db1')
103  
-            self.assertEqual(result['session_id'], 'sessionId')
104 97
             self.assertEqual(result['tags'], ['db', 'mysql'])
105 98
             self.assertEqual(result['metadata'], EXPECTED_METADATA)
  99
+            self.assertEqual(result['heartbeat_timeout'], 30)
  100
+            self.assertTrue('last_seen' in result)
106 101
 
107 102
         d = self.client.services.get('dfw1-db1')
108 103
         d.addCallback(service_assert)
@@ -112,11 +107,9 @@ def service_assert(result):
112 107
     def test_list_services(self):
113 108
         def services_assert(result):
114 109
             self.assertEqual(result['values'][0]['id'], 'dfw1-api')
115  
-            self.assertEqual(result['values'][0]['session_id'], 'sessionId')
116 110
             self.assertTrue('tags' in result['values'][0])
117 111
             self.assertTrue('metadata' in result['values'][0])
118 112
             self.assertEqual(result['values'][1]['id'], 'dfw1-db1')
119  
-            self.assertEqual(result['values'][1]['session_id'], 'sessionId')
120 113
             self.assertEqual(result['values'][1]['tags'],
121 114
                              ['db', 'mysql'])
122 115
             self.assertEqual(result['values'][1]['metadata'],
@@ -131,7 +124,6 @@ def services_assert(result):
131 124
     def test_listForTag(self):
132 125
         def services_for_tag_assert(result):
133 126
             self.assertEqual(result['values'][0]['id'], 'dfw1-db1')
134  
-            self.assertEqual(result['values'][0]['session_id'], 'sessionId')
135 127
             self.assertEqual(result['values'][0]['tags'],
136 128
                              ['db', 'mysql'])
137 129
             self.assertEqual(result['values'][0]['metadata'],
@@ -143,31 +135,6 @@ def services_for_tag_assert(result):
143 135
 
144 136
         return d
145 137
 
146  
-    def test_get_sessions(self):
147  
-        def sessions_assert(result):
148  
-            self.assertEqual(result['values'][0]['id'], 'sessionId')
149  
-            self.assertEqual(result['values'][0]['heartbeat_timeout'], 30)
150  
-            self.assertTrue('metadata' in result['values'][0])
151  
-            self.assertTrue('last_seen' in result['values'][0])
152  
-            self.assertTrue('metadata' in result)
153  
-
154  
-        d = self.client.sessions.list()
155  
-        d.addCallback(sessions_assert)
156  
-
157  
-        return d
158  
-
159  
-    def test_get_session(self):
160  
-        def session_assert(result):
161  
-            self.assertEqual(result['id'], 'sessionId')
162  
-            self.assertEqual(result['heartbeat_timeout'], 30)
163  
-            self.assertTrue('metadata' in result)
164  
-            self.assertTrue('last_seen' in result)
165  
-
166  
-        d = self.client.sessions.get('sessionId')
167  
-        d.addCallback(session_assert)
168  
-
169  
-        return d
170  
-
171 138
     def test_list_configuration(self):
172 139
         def configuration_assert(result):
173 140
             self.assertEqual(result['values'][0]['id'], 'configId')
@@ -189,20 +156,20 @@ def configuration_assert(result):
189 156
 
190 157
         return d
191 158
 
192  
-    @mock.patch("txServiceRegistry.client.BaseClient.request")
  159
+    @mock.patch('txServiceRegistry.client.BaseClient.request')
193 160
     def _marker_assertion(self, path, request):
194 161
         client = getattr(self.client, path.strip('/'))
195 162
         client.list(marker='someMarker')
196 163
         request.assert_called_with('GET', path,
197 164
                                    options={'marker': 'someMarker'})
198 165
 
199  
-    @mock.patch("txServiceRegistry.client.BaseClient.request")
  166
+    @mock.patch('txServiceRegistry.client.BaseClient.request')
200 167
     def _limit_assertion(self, path, request):
201 168
         client = getattr(self.client, path.strip('/'))
202 169
         client.list(limit=3)
203 170
         request.assert_called_with('GET', path, options={'limit': 3})
204 171
 
205  
-    @mock.patch("txServiceRegistry.client.BaseClient.request")
  172
+    @mock.patch('txServiceRegistry.client.BaseClient.request')
206 173
     def _marker_and_limit_assertion(self, path, request):
207 174
         client = getattr(self.client, path.strip('/'))
208 175
         client.list(marker='someMarker', limit=3)
@@ -213,9 +180,6 @@ def _marker_and_limit_assertion(self, path, request):
213 180
     def test_list_services_with_marker_calls_request_with_marker(self):
214 181
         return self._marker_assertion('/services')
215 182
 
216  
-    def test_list_sessions_with_marker_calls_request_with_marker(self):
217  
-        return self._marker_assertion('/sessions')
218  
-
219 183
     def test_list_events_with_marker_calls_request_with_marker(self):
220 184
         return self._marker_assertion('/events')
221 185
 
@@ -225,9 +189,6 @@ def test_list_configuration_with_marker_calls_request_with_marker(self):
225 189
     def test_list_services_with_limit_calls_request_with_limit(self):
226 190
         return self._limit_assertion('/services')
227 191
 
228  
-    def test_list_sessions_with_limit_calls_request_with_limit(self):
229  
-        return self._limit_assertion('/sessions')
230  
-
231 192
     def test_list_events_with_limit_calls_request_with_limit(self):
232 193
         return self._limit_assertion('/events')
233 194
 
@@ -237,9 +198,6 @@ def test_list_configuration_with_limit_calls_request_with_limit(self):
237 198
     def test_list_services_with_marker_and_limit(self):
238 199
         return self._marker_and_limit_assertion('/services')
239 200
 
240  
-    def test_list_sessions_request_with_marker_and_limit(self):
241  
-        return self._marker_and_limit_assertion('/sessions')
242  
-
243 201
     def test_list_events_with_mark_and_limit(self):
244 202
         return self._marker_and_limit_assertion('/events')
245 203
 
74  txServiceRegistry/test/utils.py
@@ -11,20 +11,25 @@
11 11
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 12
 # See the License for the specific language governing permissions and
13 13
 # limitations under the License.
  14
+#
  15
+# Taken from
  16
+# https://github.com/Kami/python-yubico-client/blob/master/tests/utils.py
  17
+
  18
+from __future__ import with_statement
14 19
 
15 20
 import os
  21
+import sys
16 22
 import subprocess
17 23
 import signal
18 24
 import time
19 25
 import socket
20 26
 import errno
21 27
 import atexit
22  
-from os.path import join as pjoin
23 28
 
  29
+from os.path import join as pjoin
24 30
 
25  
-# From https://github.com/Kami/python-yubico-client/blob/master/tests/utils.py
26 31
 
27  
-def waitForStartUp(process, pid, address, timeout=10):
  32
+def waitForStartUp(process, address, timeout=10):
28 33
     # connect to it, with a timeout in case something went wrong
29 34
     start = time.time()
30 35
     while time.time() < start + timeout:
@@ -38,57 +43,18 @@ def waitForStartUp(process, pid, address, timeout=10):
38 43
         # see if process is still alive
39 44
         process.poll()
40 45
 
41  
-        if pid and process.returncode is None:
42  
-            os.kill(pid, signal.SIGKILL)
  46
+        if process and process.returncode is None:
  47
+            process.terminate()
43 48
         raise RuntimeError("Couldn't connect to server; aborting test")
44 49
 
45 50
 
46 51
 class ProcessRunner(object):
47 52
     def setUp(self, *args, **kwargs):
48  
-        # clean up old.
49  
-        p = self.getPid()
50  
-        if p is not None:
51  
-            try:
52  
-                # remember, process may already be dead.
53  
-                os.kill(p, 9)
54  
-                time.sleep(0.01)
55  
-            except:
56  
-                pass
  53
+        pass
57 54
 
58 55
     def tearDown(self, *args, **kwargs):
59  
-        spid = self.getPid()
60  
-        if spid:
61  
-            max_wait = 1
62  
-            os.kill(spid, signal.SIGTERM)