Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

#!/usr/bin/env python 

# -*- coding: utf-8 -*- 

# 

# This file is part of rdlm-py released under the MIT license. 

# See the LICENSE file for more information. 

 

import requests 

import socket 

import getpass 

import os 

import sys 

from requests.auth import HTTPBasicAuth 

import json 

from rdlmpy.lock import RDLMLock 

from rdlmpy.exceptions import RDLMLockWaitExceededException 

from rdlmpy.exceptions import RDLMLockDeletedException 

from rdlmpy.exceptions import RDLMServerException 

from rdlmpy.exceptions import RDLMClientException 

from rdlmpy import __version__ as VERSION 

 

 

class RDLMClient(object): 

    ''' 

    Class which defines a client object 

    ''' 

 

    _base_url = None 

    _default_title = None 

    _default_lifetime = None 

    _default_wait = None 

 

    def __init__(self, server="localhost", port=8888, default_title=None, 

                 default_lifetime=300, default_wait=10): 

        ''' 

        @summary: constructor 

        @param server: rdlm server hostname 

        @param port: rdlm server port 

        @param default_title: default title for locks 

        @param default_lifetime: default lifetime for locks (in seconds) 

        @param default_wait: default wait time for locks (in seconds) 

        @result: client object 

        ''' 

        self._base_url = "http://%s:%i" % (server, port) 

        if default_title: 

            self._default_title = default_title 

        else: 

            self._default_title = "%s#%i(%s) with RDLMClient(%s) @%s" % ( 

                                  getpass.getuser(), os.getpid(), sys.argv[0], 

                                  VERSION, socket.gethostname()) 

        self._default_lifetime = default_lifetime 

        self._default_wait = default_wait 

 

    def lock_acquire(self, resource_name, lifetime=None, wait=None, 

                     title=None): 

        ''' 

        @summary: acquires a lock 

        @param resource_name: name of the resource to lock 

        @param lifetime: lifetime for the lock (in seconds) 

        @param wait: wait time for the lock (in seconds) 

        @param title: title 

        @result: lock url (if the lock is acquired) 

 

        If the lock is not acquired, this function can raise : 

        - a RDLMLockWaitExceededException: can't acquire the lock after 

          "wait" seconds 

        - a RDLMLockDeletedException: the request has been deleted by 

          an delete request 

        - a RDLMServerException: unknown error from the RDLM server 

        - a RDLMClientException: unknown error from the RDLM client 

        ''' 

        lock_dict = {} 

        lock_dict['lifetime'] = self._default_lifetime \ 

            if lifetime is None else lifetime 

        lock_dict['wait'] = self._default_wait if wait is None else wait 

        lock_dict['title'] = self._default_title if title is None else title 

        lock_raw = json.dumps(lock_dict) 

        try: 

            r = requests.post("%s/locks/%s" % (self._base_url, resource_name), data=lock_raw) 

        except: 

            raise RDLMServerException() 

        if r.status_code == 408: 

            raise RDLMLockWaitExceededException() 

        elif r.status_code == 409: 

            raise RDLMLockDeletedException() 

        elif r.status_code >= 400 and r.status_code < 500: 

            raise RDLMClientException() 

        elif r.status_code != 201 or not(r.headers['Location'].startswith('http://')): 

            raise RDLMServerException() 

        return r.headers['Location'] 

 

    def lock_release(self, lock_url): 

        ''' 

        @summary: releases a lock 

        @param lock_url: the lock url to release 

        @result: True (if ok), False (else) 

 

        The lock url is the return value of lock_acquire() method 

        ''' 

        try: 

            r = requests.delete(lock_url) 

        except: 

            raise RDLMServerException() 

        return (r.status_code == 204) 

 

    def lock_get(self, lock_url): 

        ''' 

        @summary: gets informations about a lock 

        @param lock_url: the lock url 

        @result: informations dict (or None) 

        ''' 

        try: 

            r = requests.get(lock_url) 

        except: 

            raise RDLMServerException() 

        if r.status_code == 200: 

            return RDLMLock.factory(lock_url, r.content.decode('utf-8')) 

        return None 

 

    def resource_delete(self, resource_name, username=None, password=None): 

        ''' 

        @summary: delete all locks on a resource 

        @param resource_name: name of the resource 

        @param username: admin http username 

        @param password: admin http password 

        @result: True if there were some locks on the resource, False else 

        ''' 

        if username and password: 

            auth = HTTPBasicAuth(username, password) 

            r = requests.delete("%s/resources/%s" % (self._base_url, resource_name), auth=auth) 

        else: 

            r = requests.delete("%s/resources/%s" % (self._base_url, resource_name)) 

        return (r.status_code == 204) 

 

    def resource_delete_all(self, username=None, password=None): 

        ''' 

        @summary: delete all locks on all resources 

        @param username: admin http username 

        @param password: admin http password 

        @result: True if ok, False else 

        ''' 

        if username and password: 

            auth = HTTPBasicAuth(username, password) 

            r = requests.delete("%s/resources" % self._base_url, auth=auth) 

        else: 

            r = requests.delete("%s/resources" % self._base_url) 

        return (r.status_code == 204) 

 

    def resource_get_all(self, username=None, password=None): 

        ''' 

        @summary: get resources list (with locks) 

        @param username: admin http username 

        @param password: admin http password 

        @result: list of resource names 

        ''' 

        if username and password: 

            auth = HTTPBasicAuth(username, password) 

            r = requests.get("%s/resources" % self._base_url, auth=auth) 

        else: 

            r = requests.get("%s/resources" % self._base_url) 

        if r.status_code != 200: 

            raise RDLMServerException("Impossible to get all resources\ 

                                      (unknown error") 

        try: 

            json_hal = json.loads(r.content) 

        except: 

            raise RDLMServerException("Impossible to get all resources\ 

                                      (can't unserialize result") 

        if '_embedded' not in json_hal or \ 

           'resources' not in json_hal['_embedded']: 

            return [] 

        return [x['name'] for x in json_hal['_embedded']['resources']] 

 

    def resource_get_all_locks(self, resource_name, username=None, password=None): 

        ''' 

        @summary: get locks list for a given resource 

        @param resource_name: name of the resource 

        @param username: admin http username 

        @param password: admin http password 

        @result: list of lock objects 

        ''' 

        if username and password: 

            auth = HTTPBasicAuth(username, password) 

            r = requests.get("%s/resources/%s" % (self._base_url, resource_name), auth=auth) 

        else: 

            r = requests.get("%s/resources/%s" % (self._base_url, resource_name)) 

        if r.status_code != 200: 

            raise RDLMServerException("Impossible to get all locks\ 

                                      (unknown error") 

        try: 

            json_hal = json.loads(r.content.decode('utf-8')) 

        except: 

            raise RDLMServerException("Impossible to get all locks\ 

                                      (can't unserialize result") 

        if '_embedded' not in json_hal or \ 

           'locks' not in json_hal['_embedded']: 

            return [] 

        out = [] 

        for x in json_hal['_embedded']['locks']: 

            lock_url = "%s%s" % (self._base_url, x['_links']['self']['href']) 

            out.append(RDLMLock.factory(lock_url, json.dumps(x))) 

        return out