Migrate request invocations (controller)
[integration/test.git] / csit / libraries / IoTDM / iotdm.py
1 import requests
2 from datetime import timedelta
3
4 zero = timedelta(0)
5
6 application = 2
7 container = 3
8 contentInstance = 4
9
10 op_provision = ":8181/restconf/operations/onem2m:onem2m-cse-provisioning"
11 op_tree = ":8181/restconf/operational/onem2m:onem2m-resource-tree"
12 op_cleanup = ":8181/restconf/operations/onem2m:onem2m-cleanup-store"
13
14 cse_payload = """
15 {    "input": {
16         "onem2m-primitive": [
17            {
18                 "name": "CSE_ID",
19                 "value": "%s"
20             },
21             {
22                 "name": "CSE_TYPE",
23                 "value": "IN-CSE"
24             }
25         ]
26     }
27 }
28 """
29
30 application_payload = """
31 {
32   any:
33   [
34     {"aei":"jb", "api":"jb", "apn":"jb2", "or":"http://hey/you" %s}
35   ]
36 }
37 """
38
39 _container_payload = """
40 {
41   any:
42   [
43     {
44       "cr": "jb",
45       "mni": 1,
46       "mbs": 3,
47       "or": "http://hey/you"
48       %s
49     }
50   ]
51 }
52 """
53
54 container_payload = """
55 {
56   any:
57   [
58     {
59       "cr": "jb",
60       "or": "http://hey/you"
61       %s
62     }
63   ]
64 }
65 """
66
67 contentInstance_payload = """
68 {
69   "any": [
70     {
71       "cnf": "1",
72       "or": "http://hey/you"
73       %s
74     }
75   ]
76 }
77 """
78
79
80 def which_payload(restype):
81     """Return a template payload for the known datatypes."""
82     if restype == application:
83         return application_payload
84     elif restype == container:
85         return container_payload
86     elif restype == contentInstance:
87         return contentInstance_payload
88     else:
89         return ""
90
91
92 def find_key(response, key):
93     try:
94         val = response.json()
95         return val["any"][0][key]
96     except Exception:
97         return None
98
99
100 def name(response):
101     """Return the resource name in the response."""
102     return find_key(response, "rn")
103
104
105 def resid(response):
106     """Return the resource id in the response."""
107     return find_key(response, "ri")
108
109
110 def parent(response):
111     """Return the parent resource id in the response."""
112     return find_key(response, "pi")
113
114
115 def content(response):
116     """Return the content the response."""
117     return find_key(response, "con")
118
119
120 def restype(response):
121     """Return the resource type the response."""
122     return find_key(response, "rty")
123
124
125 def status(response):
126     """Return the protocol status code in the response."""
127     try:
128         return response.status_code
129     except Exception:
130         return None
131
132
133 def headers(response):
134     """Return the protocol headers in the response."""
135     try:
136         return response.headers
137     except Exception:
138         return None
139
140
141 def error(response):
142     """Return the error string in the response."""
143     try:
144         return response.json()["error"]
145     except Exception:
146         return None
147
148
149 def normalize(id):
150     if id is not None:
151         if id[0] == "/":
152             return id[1:]
153     return id
154
155
156 def attr2str(attr):
157     """Convert a dictionary into a string for a protocol payload."""
158     content = ""
159     if attr is not None:
160         content = ","
161         n = len(attr)
162         c = 1
163         sep = ","
164         for i in attr:
165             if n == c:
166                 sep = ""
167             n = str(attr[i])
168             if i != "con" and n.isdigit():
169                 content = content + "'%s':%d%s" % (i, int(n), sep)
170             else:
171                 content = content + "'%s':'%s'%s" % (i, n, sep)
172             c = c + 1
173     return content
174
175
176 class connect:
177     def __init__(
178         self,
179         server="localhost",
180         base="InCSE1",
181         auth=("admin", "admin"),
182         protocol="http",
183     ):
184         """Connect to a IoTDM server."""
185         self.s = requests.Session()
186         self.s.auth = auth
187         self.s.headers.update({"content-type": "application/json"})
188         self.timeout = (5, 5)
189         self.payload = cse_payload % (base)
190         self.headers = {
191             # Admittedly these are "magic values" but are required
192             # and until a proper defaulting initializer is in place
193             # are hard-coded.
194             "content-type": "application/json",
195             "X-M2M-Origin": "//localhost:10000",
196             "X-M2M-RI": "12345",
197             "X-M2M-OT": "NOW",
198         }
199         self.server = "http://" + server
200         if base is not None:
201             self.url = self.server + op_provision
202             self.r = self.s.post(self.url, data=self.payload, timeout=self.timeout)
203
204     def create(self, parent, restype, name=None, attr=None):
205         """Create resource."""
206         if parent is None:
207             return None
208         payload = which_payload(restype)
209         payload = payload % (attr2str(attr))
210         if name is None:
211             self.headers["X-M2M-NM"] = None
212         else:
213             self.headers["X-M2M-NM"] = name
214         parent = normalize(parent)
215         self.url = self.server + ":8282/%s?ty=%s&rcn=1" % (parent, restype)
216         self.r = self.s.post(
217             self.url, payload, timeout=self.timeout, headers=self.headers
218         )
219         return self.r
220
221     def retrieve(self, id):
222         """Retrieve resource."""
223         if id is None:
224             return None
225         id = normalize(id)
226         self.url = self.server + ":8282/%s?rcn=5&drt=2" % (id)
227         self.headers["X-M2M-NM"] = None
228         self.r = self.s.get(self.url, timeout=self.timeout, headers=self.headers)
229         return self.r
230
231     def update(self, id, attr=None):
232         """Update resource attr"""
233         if id is None:
234             return None
235         id = normalize(id)
236         return None
237
238     def delete(self, id):
239         """Delete the resource with the provided ID."""
240         if id is None:
241             return None
242         id = normalize(id)
243         self.url = self.server + ":8282/%s" % (id)
244         self.headers["X-M2M-NM"] = None
245         self.r = self.s.delete(self.url, timeout=self.timeout, headers=self.headers)
246         return self.r
247
248     def tree(self):
249         """Get the resource tree."""
250         self.url = self.server + op_tree
251         self.r = self.s.get(self.url)
252         return self.r
253
254     def kill(self):
255         """Kill the tree."""
256         self.url = self.server + op_cleanup
257         self.r = self.s.post(self.url)
258         return self.r