pyxecm 1.6__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm/__init__.py +6 -4
- pyxecm/avts.py +673 -246
- pyxecm/coreshare.py +686 -467
- pyxecm/customizer/__init__.py +16 -4
- pyxecm/customizer/__main__.py +58 -0
- pyxecm/customizer/api/__init__.py +5 -0
- pyxecm/customizer/api/__main__.py +6 -0
- pyxecm/customizer/api/app.py +914 -0
- pyxecm/customizer/api/auth.py +154 -0
- pyxecm/customizer/api/metrics.py +92 -0
- pyxecm/customizer/api/models.py +13 -0
- pyxecm/customizer/api/payload_list.py +865 -0
- pyxecm/customizer/api/settings.py +103 -0
- pyxecm/customizer/browser_automation.py +332 -139
- pyxecm/customizer/customizer.py +1007 -1130
- pyxecm/customizer/exceptions.py +35 -0
- pyxecm/customizer/guidewire.py +322 -0
- pyxecm/customizer/k8s.py +713 -378
- pyxecm/customizer/log.py +107 -0
- pyxecm/customizer/m365.py +2867 -909
- pyxecm/customizer/nhc.py +1169 -0
- pyxecm/customizer/openapi.py +258 -0
- pyxecm/customizer/payload.py +16817 -7467
- pyxecm/customizer/pht.py +699 -285
- pyxecm/customizer/salesforce.py +516 -342
- pyxecm/customizer/sap.py +58 -41
- pyxecm/customizer/servicenow.py +593 -371
- pyxecm/customizer/settings.py +442 -0
- pyxecm/customizer/successfactors.py +408 -346
- pyxecm/customizer/translate.py +83 -48
- pyxecm/helper/__init__.py +5 -2
- pyxecm/helper/assoc.py +83 -43
- pyxecm/helper/data.py +2406 -870
- pyxecm/helper/logadapter.py +27 -0
- pyxecm/helper/web.py +229 -101
- pyxecm/helper/xml.py +527 -171
- pyxecm/maintenance_page/__init__.py +5 -0
- pyxecm/maintenance_page/__main__.py +6 -0
- pyxecm/maintenance_page/app.py +51 -0
- pyxecm/maintenance_page/settings.py +28 -0
- pyxecm/maintenance_page/static/favicon.avif +0 -0
- pyxecm/maintenance_page/templates/maintenance.html +165 -0
- pyxecm/otac.py +234 -140
- pyxecm/otawp.py +1436 -557
- pyxecm/otcs.py +7716 -3161
- pyxecm/otds.py +2150 -919
- pyxecm/otiv.py +36 -21
- pyxecm/otmm.py +1272 -325
- pyxecm/otpd.py +231 -127
- pyxecm-2.0.0.dist-info/METADATA +145 -0
- pyxecm-2.0.0.dist-info/RECORD +54 -0
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info}/WHEEL +1 -1
- pyxecm-1.6.dist-info/METADATA +0 -53
- pyxecm-1.6.dist-info/RECORD +0 -32
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info/licenses}/LICENSE +0 -0
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info}/top_level.txt +0 -0
pyxecm/otawp.py
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
""
|
|
1
|
+
"""Synchronize AppWorks projects, publsh and create run time instances for that."""
|
|
2
|
+
|
|
3
|
+
__author__ = "Dr. Marc Diefenbruch"
|
|
4
|
+
__copyright__ = "Copyright (C) 2024-2025, OpenText"
|
|
5
|
+
__credits__ = ["Kai-Philip Gatzweiler"]
|
|
6
|
+
__maintainer__ = "Dr. Marc Diefenbruch"
|
|
7
|
+
__email__ = "mdiefenb@opentext.com"
|
|
5
8
|
|
|
6
|
-
import logging
|
|
7
|
-
import xml.etree.ElementTree as ET
|
|
8
|
-
import uuid
|
|
9
9
|
import json
|
|
10
|
+
import logging
|
|
10
11
|
import re
|
|
11
12
|
import time
|
|
13
|
+
import uuid
|
|
14
|
+
import xml.etree.ElementTree as ET
|
|
15
|
+
|
|
12
16
|
import requests
|
|
13
|
-
from .otds import OTDS
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
from pyxecm.otds import OTDS
|
|
19
|
+
|
|
20
|
+
default_logger = logging.getLogger("pyxecm.otawp")
|
|
16
21
|
|
|
17
22
|
REQUEST_HEADERS = {
|
|
18
23
|
"Content-Type": "text/xml; charset=utf-8",
|
|
19
|
-
"accept": "application/xml"
|
|
24
|
+
"accept": "application/xml",
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
REQUEST_FORM_HEADERS = {
|
|
@@ -26,12 +31,17 @@ REQUEST_FORM_HEADERS = {
|
|
|
26
31
|
|
|
27
32
|
REQUEST_HEADERS_JSON = {
|
|
28
33
|
"Content-Type": "application/json; charset=utf-8",
|
|
29
|
-
"accept": "application/json"
|
|
34
|
+
"accept": "application/json",
|
|
30
35
|
}
|
|
31
|
-
REQUEST_TIMEOUT =
|
|
36
|
+
REQUEST_TIMEOUT = 120
|
|
37
|
+
SYNC_PUBLISH_REQUEST_TIMEOUT = 300
|
|
38
|
+
|
|
32
39
|
|
|
33
40
|
class OTAWP:
|
|
34
|
-
"""
|
|
41
|
+
"""Class OTRAWP is used to automate settings in OpenText AppWorks Platform (OTAWP)."""
|
|
42
|
+
|
|
43
|
+
logger: logging.Logger = default_logger
|
|
44
|
+
|
|
35
45
|
_config: dict
|
|
36
46
|
_config = None
|
|
37
47
|
_cookie = None
|
|
@@ -45,7 +55,46 @@ class OTAWP:
|
|
|
45
55
|
username: str | None = None,
|
|
46
56
|
password: str | None = None,
|
|
47
57
|
otawp_ticket: str | None = None,
|
|
48
|
-
|
|
58
|
+
otcs_partition_name: str | None = None,
|
|
59
|
+
otds_admin_partition_mame: str | None = None,
|
|
60
|
+
config_map_name: str | None = None,
|
|
61
|
+
otcs_resource_id: str | None = None,
|
|
62
|
+
otds_url: str | None = None,
|
|
63
|
+
otcs_url: str | None = None,
|
|
64
|
+
otcs_base_path: str | None = None,
|
|
65
|
+
license_file: str | None = None,
|
|
66
|
+
product_name: str | None = None,
|
|
67
|
+
product_description: str | None = None,
|
|
68
|
+
logger: logging.Logger = default_logger,
|
|
69
|
+
) -> None:
|
|
70
|
+
"""Initialize OTAWP (AppWorks Platform) object.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
protocol (str): #TODO _description_
|
|
74
|
+
hostname (str): #TODO _description_
|
|
75
|
+
port (int): #TODO _description_
|
|
76
|
+
username (str | None, optional): #TODO _description_. Defaults to None.
|
|
77
|
+
password (str | None, optional): #TODO _description_. Defaults to None.
|
|
78
|
+
otawp_ticket (str | None, optional): #TODO _description_. Defaults to None.
|
|
79
|
+
otcs_partition_name (str | None, optional): #TODO _description_. Defaults to None.
|
|
80
|
+
otds_admin_partition_mame (str | None, optional): #TODO _description_. Defaults to None.
|
|
81
|
+
config_map_name (str | None, optional): #TODO _description_. Defaults to None.
|
|
82
|
+
otcs_resource_id (str | None, optional): #TODO _description_. Defaults to None.
|
|
83
|
+
otds_url (str | None, optional): #TODO _description_. Defaults to None.
|
|
84
|
+
otcs_url (str | None, optional): #TODO _description_. Defaults to None.
|
|
85
|
+
otcs_base_path (str | None, optional): #TODO _description_. Defaults to None.
|
|
86
|
+
license_file (str | None, optional): #TODO _description_. Defaults to None.
|
|
87
|
+
product_name (str | None, optional): #TODO _description_. Defaults to None.
|
|
88
|
+
product_description (str | None, optional): #TODO _description_. Defaults to None.
|
|
89
|
+
logger (logging.Logger, optional): #TODO: _description_. Defaults to default_logger.
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
if logger != default_logger:
|
|
94
|
+
self.logger = logger.getChild("otawp")
|
|
95
|
+
for logfilter in logger.filters:
|
|
96
|
+
self.logger.addFilter(logfilter)
|
|
97
|
+
|
|
49
98
|
otawp_config = {}
|
|
50
99
|
|
|
51
100
|
otawp_config["hostname"] = hostname if hostname else "appworks"
|
|
@@ -53,125 +102,332 @@ class OTAWP:
|
|
|
53
102
|
otawp_config["port"] = port if port else 8080
|
|
54
103
|
otawp_config["username"] = username if username else "sysadmin"
|
|
55
104
|
otawp_config["password"] = password if password else ""
|
|
105
|
+
otawp_config["otcs_partition_name"] = otcs_partition_name if otcs_partition_name else ""
|
|
106
|
+
otawp_config["otds_admin_partition_mame"] = otds_admin_partition_mame if otds_admin_partition_mame else ""
|
|
107
|
+
otawp_config["config_map_name"] = config_map_name if config_map_name else ""
|
|
108
|
+
otawp_config["otcs_resource_id"] = otcs_resource_id if otcs_resource_id else ""
|
|
109
|
+
otawp_config["otds_url"] = otds_url if otds_url else ""
|
|
110
|
+
otawp_config["otcs_url"] = otcs_url if otcs_url else ""
|
|
111
|
+
otawp_config["otcs_base_path"] = otcs_base_path if otcs_base_path else ""
|
|
112
|
+
otawp_config["license_file"] = license_file if license_file else ""
|
|
113
|
+
otawp_config["product_name"] = product_name if product_name else "APPWORKS_PLATFORM"
|
|
114
|
+
otawp_config["product_description"] = (
|
|
115
|
+
product_description if product_description else "OpenText Appworks Platform"
|
|
116
|
+
)
|
|
56
117
|
|
|
57
118
|
if otawp_ticket:
|
|
58
119
|
self._cookie = {"defaultinst_SAMLart": otawp_ticket}
|
|
59
120
|
|
|
60
|
-
|
|
121
|
+
server = "{}://{}".format(protocol, otawp_config["hostname"])
|
|
61
122
|
if str(port) not in ["80", "443"]:
|
|
62
|
-
|
|
63
|
-
|
|
123
|
+
server += f":{port}"
|
|
124
|
+
|
|
125
|
+
otawp_base_url = server + "/home/system"
|
|
126
|
+
|
|
127
|
+
otawp_config["server"] = server if server else "http://appworks"
|
|
64
128
|
|
|
65
129
|
otawp_config["gatewayAuthenticationUrl"] = (
|
|
66
|
-
|
|
130
|
+
otawp_base_url
|
|
67
131
|
+ "/com.eibus.web.soap.Gateway.wcp?organization=o=system,cn=cordys,cn=defaultInst,o=opentext.net"
|
|
68
132
|
)
|
|
69
133
|
|
|
70
134
|
otawp_config["soapGatewayUrl"] = (
|
|
71
|
-
|
|
135
|
+
otawp_base_url
|
|
72
136
|
+ "/com.eibus.web.soap.Gateway.wcp?organization=o=system,cn=cordys,cn=defaultInst,o=opentext.net&defaultinst_ct=abcd"
|
|
73
137
|
)
|
|
74
138
|
|
|
75
139
|
otawp_config["createPriority"] = (
|
|
76
|
-
|
|
77
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Priority?defaultinst_ct=abcd"
|
|
140
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Priority?defaultinst_ct=abcd"
|
|
78
141
|
)
|
|
79
142
|
otawp_config["getAllPriorities"] = (
|
|
80
|
-
|
|
81
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Priority/lists/PriorityList"
|
|
143
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Priority/lists/PriorityList"
|
|
82
144
|
)
|
|
83
145
|
|
|
84
146
|
otawp_config["createCustomer"] = (
|
|
85
|
-
|
|
86
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Customer?defaultinst_ct=abcd"
|
|
147
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Customer?defaultinst_ct=abcd"
|
|
87
148
|
)
|
|
88
|
-
otawp_config["
|
|
89
|
-
|
|
90
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Customer/lists/CustomerList"
|
|
149
|
+
otawp_config["getAllCustomers"] = (
|
|
150
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Customer/lists/CustomerList"
|
|
91
151
|
)
|
|
92
152
|
|
|
93
153
|
otawp_config["createCaseType"] = (
|
|
94
|
-
|
|
95
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/CaseType?defaultinst_ct=abcd"
|
|
154
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/CaseType?defaultinst_ct=abcd"
|
|
96
155
|
)
|
|
97
156
|
otawp_config["getAllCaseTypes"] = (
|
|
98
|
-
|
|
99
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/CaseType/lists/AllCaseTypes"
|
|
157
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/CaseType/lists/AllCaseTypes"
|
|
100
158
|
)
|
|
101
159
|
|
|
102
160
|
otawp_config["createCategory"] = (
|
|
103
|
-
|
|
104
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Category?defaultinst_ct=abcd"
|
|
161
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Category?defaultinst_ct=abcd"
|
|
105
162
|
)
|
|
106
163
|
otawp_config["getAllCategories"] = (
|
|
107
|
-
|
|
108
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Category/lists/CategoryList"
|
|
164
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Category/lists/CategoryList"
|
|
109
165
|
)
|
|
110
166
|
|
|
111
167
|
otawp_config["createSource"] = (
|
|
112
|
-
|
|
113
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Source"
|
|
168
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Source"
|
|
114
169
|
)
|
|
115
170
|
|
|
116
171
|
otawp_config["getAllSources"] = (
|
|
117
|
-
|
|
118
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Source/lists/AllSources"
|
|
172
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Source/lists/AllSources"
|
|
119
173
|
)
|
|
120
174
|
|
|
121
175
|
otawp_config["getAllSubCategories"] = (
|
|
122
|
-
|
|
176
|
+
otawp_base_url
|
|
123
177
|
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Category/childEntities/SubCategory/lists/AllSubcategories"
|
|
124
178
|
)
|
|
125
179
|
|
|
126
|
-
otawp_config["baseurl"] =
|
|
127
|
-
otds_base_url
|
|
128
|
-
+ ""
|
|
129
|
-
)
|
|
180
|
+
otawp_config["baseurl"] = otawp_base_url + ""
|
|
130
181
|
otawp_config["createLoan"] = (
|
|
131
|
-
|
|
132
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Case?defaultinst_ct=abcd"
|
|
182
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Case?defaultinst_ct=abcd"
|
|
133
183
|
)
|
|
134
184
|
otawp_config["getAllLoans"] = (
|
|
135
|
-
|
|
136
|
-
+ "/app/entityRestService/api/OpentextCaseManagement/entities/Case/lists/AllCasesList"
|
|
185
|
+
otawp_base_url + "/app/entityRestService/api/OpentextCaseManagement/entities/Case/lists/AllCasesList"
|
|
137
186
|
)
|
|
138
187
|
self._config = otawp_config
|
|
139
188
|
|
|
140
189
|
# end method definition
|
|
141
190
|
|
|
142
|
-
def
|
|
143
|
-
"""
|
|
191
|
+
def server(self) -> str:
|
|
192
|
+
"""Return server information.
|
|
193
|
+
|
|
144
194
|
Returns:
|
|
145
|
-
|
|
195
|
+
str:
|
|
196
|
+
Server configuration.
|
|
197
|
+
|
|
146
198
|
"""
|
|
199
|
+
|
|
200
|
+
return self.config()["server"]
|
|
201
|
+
|
|
202
|
+
# end method definition
|
|
203
|
+
|
|
204
|
+
def set_organization(self, organization: str) -> None:
|
|
205
|
+
"""Set the organization context.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
organization (str):
|
|
209
|
+
Organization name.
|
|
210
|
+
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
otawp_base_url = f"/home/{organization}"
|
|
214
|
+
otawp_url = self.server() + otawp_base_url
|
|
215
|
+
ldap_root = (
|
|
216
|
+
f"com.eibus.web.soap.Gateway.wcp?organization=o={organization},cn=cordys,cn=defaultInst,o=opentext.net"
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Assign to self._config if that's where you store configuration data
|
|
220
|
+
self._config["gatewayAuthenticationUrl"] = otawp_url + f"/com.eibus.web.soap.Gateway.wcp?{ldap_root}"
|
|
221
|
+
|
|
222
|
+
self._config["soapGatewayUrl"] = otawp_url + f"/com.eibus.web.soap.Gateway.wcp?{ldap_root}&defaultinst_ct=abcd"
|
|
223
|
+
|
|
224
|
+
self.logger.info("Organization set to '%s'.", organization)
|
|
225
|
+
|
|
226
|
+
# end method definition
|
|
227
|
+
|
|
228
|
+
def baseurl(self) -> str:
|
|
229
|
+
"""Return the configuration dictionary.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
str:
|
|
233
|
+
Base URL of AppWorks Platform.
|
|
234
|
+
|
|
235
|
+
"""
|
|
236
|
+
|
|
147
237
|
return self.config()["baseurl"]
|
|
148
238
|
|
|
149
239
|
# end method definition
|
|
150
240
|
|
|
241
|
+
def license_file(self) -> str:
|
|
242
|
+
"""Return the license_file.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
str:
|
|
246
|
+
Returns license_file
|
|
247
|
+
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
return self.config()["license_file"]
|
|
251
|
+
|
|
252
|
+
# end method definition
|
|
253
|
+
|
|
254
|
+
def product_name(self) -> str:
|
|
255
|
+
"""Return the product_name.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
str:
|
|
259
|
+
Returns product_name
|
|
260
|
+
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
return self.config()["product_name"]
|
|
264
|
+
|
|
265
|
+
# end method definition
|
|
266
|
+
|
|
267
|
+
def product_description(self) -> str:
|
|
268
|
+
"""Return the product_description.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
str:
|
|
272
|
+
Returns product_description
|
|
273
|
+
|
|
274
|
+
"""
|
|
275
|
+
|
|
276
|
+
return self.config()["product_description"]
|
|
277
|
+
|
|
278
|
+
# end method definition
|
|
279
|
+
|
|
280
|
+
def hostname(self) -> str:
|
|
281
|
+
"""Return hostname.
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
str: Returns hostname
|
|
285
|
+
|
|
286
|
+
"""
|
|
287
|
+
|
|
288
|
+
return self.config()["hostname"]
|
|
289
|
+
|
|
290
|
+
def username(self) -> str:
|
|
291
|
+
"""Return username.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
str: Returns username
|
|
295
|
+
|
|
296
|
+
"""
|
|
297
|
+
return self.config()["username"]
|
|
298
|
+
|
|
299
|
+
# end method definition
|
|
300
|
+
|
|
301
|
+
def password(self) -> str:
|
|
302
|
+
"""Return password.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
str: Returns password
|
|
306
|
+
|
|
307
|
+
"""
|
|
308
|
+
return self.config()["password"]
|
|
309
|
+
|
|
310
|
+
# end method definition
|
|
311
|
+
|
|
312
|
+
def otcs_partition_name(self) -> str:
|
|
313
|
+
"""Return OTCS partition name.
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
str: Returns OTCS partition name
|
|
317
|
+
|
|
318
|
+
"""
|
|
319
|
+
return self.config()["otcs_partition_name"]
|
|
320
|
+
|
|
321
|
+
# end method definition
|
|
322
|
+
|
|
323
|
+
def otds_admin_partition_mame(self) -> str:
|
|
324
|
+
"""Return OTDS admin partition name.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
str:
|
|
328
|
+
Returns OTDS admin partition mame.
|
|
329
|
+
|
|
330
|
+
"""
|
|
331
|
+
|
|
332
|
+
return self.config()["otds_admin_partition_mame"]
|
|
333
|
+
|
|
334
|
+
# end method definition
|
|
335
|
+
|
|
336
|
+
def config_map_name(self) -> str:
|
|
337
|
+
"""Return config map name.
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
str:
|
|
341
|
+
Returns config map name
|
|
342
|
+
|
|
343
|
+
"""
|
|
344
|
+
return self.config()["config_map_name"]
|
|
345
|
+
|
|
346
|
+
# end method definition
|
|
347
|
+
|
|
348
|
+
def otcs_resource_id(self) -> str:
|
|
349
|
+
"""Return OTCS resource ID.
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
str:
|
|
353
|
+
Returns otcs resource id
|
|
354
|
+
|
|
355
|
+
"""
|
|
356
|
+
return self.config()["otcs_resource_id"]
|
|
357
|
+
|
|
358
|
+
# end method definition
|
|
359
|
+
|
|
360
|
+
def otcs_url(self) -> str:
|
|
361
|
+
"""Return OTCS URL.
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
str:
|
|
365
|
+
Returns the OTCS URL.
|
|
366
|
+
|
|
367
|
+
"""
|
|
368
|
+
return self.config()["otcs_url"]
|
|
369
|
+
|
|
370
|
+
# end method definition
|
|
371
|
+
|
|
372
|
+
def otds_url(self) -> str:
|
|
373
|
+
"""Return the OTDS URL.
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
str:
|
|
377
|
+
Returns otds url
|
|
378
|
+
|
|
379
|
+
"""
|
|
380
|
+
return self.config()["otds_url"]
|
|
381
|
+
|
|
382
|
+
# end method definition
|
|
383
|
+
|
|
384
|
+
def otcs_base_path(self) -> str:
|
|
385
|
+
"""Return the OTCS base path.
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
str: Returns otcs base path
|
|
389
|
+
|
|
390
|
+
"""
|
|
391
|
+
return self.config()["otcs_base_path"]
|
|
392
|
+
|
|
393
|
+
# end method definition
|
|
394
|
+
|
|
151
395
|
def config(self) -> dict:
|
|
152
|
-
"""
|
|
396
|
+
"""Return the configuration dictionary.
|
|
397
|
+
|
|
153
398
|
Returns:
|
|
154
399
|
dict: Configuration dictionary
|
|
400
|
+
|
|
155
401
|
"""
|
|
402
|
+
|
|
156
403
|
return self._config
|
|
157
404
|
|
|
158
405
|
# end method definition
|
|
159
406
|
|
|
160
407
|
def cookie(self) -> dict:
|
|
161
|
-
"""
|
|
162
|
-
|
|
408
|
+
"""Return the login cookie of OTAWP.
|
|
409
|
+
|
|
410
|
+
This is set by the authenticate() method
|
|
411
|
+
|
|
163
412
|
Returns:
|
|
164
|
-
dict:
|
|
413
|
+
dict:
|
|
414
|
+
OTAWP cookie
|
|
415
|
+
|
|
165
416
|
"""
|
|
417
|
+
|
|
166
418
|
return self._cookie
|
|
167
419
|
|
|
168
420
|
# end method definition
|
|
169
421
|
|
|
170
422
|
def credentials(self) -> str:
|
|
171
|
-
"""
|
|
423
|
+
"""Return the SOAP payload with credentials (username and password).
|
|
424
|
+
|
|
172
425
|
Returns:
|
|
173
|
-
str:
|
|
426
|
+
str:
|
|
427
|
+
SOAP payload with username and password.
|
|
428
|
+
|
|
174
429
|
"""
|
|
430
|
+
|
|
175
431
|
username = self.config()["username"]
|
|
176
432
|
password = self.config()["password"]
|
|
177
433
|
|
|
@@ -199,146 +455,196 @@ class OTAWP:
|
|
|
199
455
|
</SOAP:Body>
|
|
200
456
|
</SOAP:Envelope>
|
|
201
457
|
"""
|
|
458
|
+
|
|
202
459
|
return soap_payload
|
|
203
460
|
|
|
204
461
|
# end method definition
|
|
205
462
|
|
|
206
463
|
def credential_url(self) -> str:
|
|
207
|
-
"""
|
|
464
|
+
"""Return the Credentials URL of OTAWP.
|
|
208
465
|
|
|
209
466
|
Returns:
|
|
210
467
|
str: Credentials URL
|
|
468
|
+
|
|
211
469
|
"""
|
|
470
|
+
|
|
212
471
|
return self.config()["gatewayAuthenticationUrl"]
|
|
213
472
|
|
|
214
473
|
# end method definition
|
|
215
474
|
|
|
216
475
|
def gateway_url(self) -> str:
|
|
217
|
-
"""
|
|
476
|
+
"""Return SOAP gateway URL of OTAWP.
|
|
218
477
|
|
|
219
478
|
Returns:
|
|
220
|
-
str:
|
|
479
|
+
str:
|
|
480
|
+
The SOAP gateway URL.
|
|
481
|
+
|
|
221
482
|
"""
|
|
483
|
+
|
|
222
484
|
return self.config()["soapGatewayUrl"]
|
|
223
485
|
|
|
224
486
|
# end method definition
|
|
225
487
|
|
|
226
488
|
def create_priority_url(self) -> str:
|
|
227
|
-
"""
|
|
489
|
+
"""Return create priority URL of OTAWP.
|
|
228
490
|
|
|
229
491
|
Returns:
|
|
230
492
|
str: createPriority URL
|
|
493
|
+
|
|
231
494
|
"""
|
|
495
|
+
|
|
232
496
|
return self.config()["createPriority"]
|
|
233
497
|
|
|
234
498
|
# end method definition
|
|
235
499
|
|
|
236
500
|
def get_all_priorities_url(self) -> str:
|
|
237
|
-
"""
|
|
501
|
+
"""Return get all priorities URL of OTAWP.
|
|
238
502
|
|
|
239
503
|
Returns:
|
|
240
|
-
str:
|
|
504
|
+
str:
|
|
505
|
+
The getAllPriorities URL of OTAWP.
|
|
506
|
+
|
|
241
507
|
"""
|
|
508
|
+
|
|
242
509
|
return self.config()["getAllPriorities"]
|
|
243
510
|
|
|
244
511
|
# end method definition
|
|
245
512
|
|
|
246
513
|
def create_customer_url(self) -> str:
|
|
247
|
-
"""
|
|
514
|
+
"""Return create customer URL of OTAWP.
|
|
248
515
|
|
|
249
516
|
Returns:
|
|
250
|
-
str:
|
|
517
|
+
str:
|
|
518
|
+
The create customer URL.
|
|
519
|
+
|
|
251
520
|
"""
|
|
521
|
+
|
|
252
522
|
return self.config()["createCustomer"]
|
|
253
523
|
|
|
254
524
|
# end method definition
|
|
255
525
|
|
|
256
526
|
def get_all_customeres_url(self) -> str:
|
|
257
|
-
"""
|
|
527
|
+
"""Return get all customers URL of OTAWP.
|
|
258
528
|
|
|
259
529
|
Returns:
|
|
260
|
-
str:
|
|
530
|
+
str:
|
|
531
|
+
The get all customers URL.
|
|
532
|
+
|
|
261
533
|
"""
|
|
262
|
-
|
|
534
|
+
|
|
535
|
+
return self.config()["getAllCustomers"]
|
|
263
536
|
|
|
264
537
|
# end method definition
|
|
265
538
|
|
|
266
539
|
def create_casetype_url(self) -> str:
|
|
267
|
-
"""
|
|
540
|
+
"""Return create case type URL of OTAWP.
|
|
268
541
|
|
|
269
542
|
Returns:
|
|
270
|
-
str:
|
|
543
|
+
str:
|
|
544
|
+
The create case type URL.
|
|
545
|
+
|
|
271
546
|
"""
|
|
547
|
+
|
|
272
548
|
return self.config()["createCaseType"]
|
|
273
549
|
|
|
274
550
|
# end method definition
|
|
275
551
|
|
|
276
552
|
def get_all_case_types_url(self) -> str:
|
|
277
|
-
"""
|
|
553
|
+
"""Return get all case types URL of OTAWP.
|
|
278
554
|
|
|
279
555
|
Returns:
|
|
280
|
-
str:
|
|
556
|
+
str:
|
|
557
|
+
The get all case types URL.
|
|
558
|
+
|
|
281
559
|
"""
|
|
560
|
+
|
|
282
561
|
return self.config()["getAllCaseTypes"]
|
|
283
562
|
|
|
284
563
|
# end method definition
|
|
285
564
|
|
|
286
565
|
def create_category_url(self) -> str:
|
|
287
|
-
"""
|
|
566
|
+
"""Return create category URL of OTAWP.
|
|
288
567
|
|
|
289
568
|
Returns:
|
|
290
|
-
str:
|
|
569
|
+
str:
|
|
570
|
+
The create category URL.
|
|
571
|
+
|
|
291
572
|
"""
|
|
573
|
+
|
|
292
574
|
return self.config()["createCategory"]
|
|
293
575
|
|
|
294
576
|
# end method definition
|
|
295
577
|
|
|
296
578
|
def get_all_categories_url(self) -> str:
|
|
297
|
-
"""
|
|
579
|
+
"""Return the get all categories URL of OTAWP.
|
|
298
580
|
|
|
299
581
|
Returns:
|
|
300
|
-
str:
|
|
582
|
+
str:
|
|
583
|
+
The get all categories URL.
|
|
584
|
+
|
|
301
585
|
"""
|
|
586
|
+
|
|
302
587
|
return self.config()["getAllCategories"]
|
|
303
588
|
|
|
304
589
|
# end method definition
|
|
305
590
|
|
|
306
591
|
def get_all_loans_url(self) -> str:
|
|
307
|
-
"""
|
|
592
|
+
"""Return get all loans URL of OTAWP.
|
|
308
593
|
|
|
309
594
|
Returns:
|
|
310
|
-
str:
|
|
595
|
+
str:
|
|
596
|
+
The get all loans URL.
|
|
597
|
+
|
|
311
598
|
"""
|
|
599
|
+
|
|
312
600
|
return self.config()["getAllLoans"]
|
|
313
601
|
|
|
314
602
|
# end method definition
|
|
315
603
|
|
|
316
|
-
def remove_namespace(self, tag):
|
|
604
|
+
def remove_namespace(self, tag: str) -> str:
|
|
317
605
|
"""Remove namespace from XML tag."""
|
|
318
|
-
|
|
606
|
+
|
|
607
|
+
return tag.split("}", 1)[-1]
|
|
319
608
|
|
|
320
609
|
# end method definition
|
|
321
610
|
|
|
322
|
-
def parse_xml(self, xml_string):
|
|
611
|
+
def parse_xml(self, xml_string: str) -> dict:
|
|
323
612
|
"""Parse XML string and return a dictionary without namespaces."""
|
|
324
|
-
|
|
613
|
+
|
|
614
|
+
def element_to_dict(element) -> dict: # noqa: ANN001
|
|
325
615
|
"""Convert XML element to dictionary."""
|
|
326
616
|
tag = self.remove_namespace(element.tag)
|
|
327
617
|
children = list(element)
|
|
328
618
|
if children:
|
|
329
|
-
return {
|
|
619
|
+
return {
|
|
620
|
+
tag: {self.remove_namespace(child.tag): element_to_dict(child) for child in children},
|
|
621
|
+
}
|
|
330
622
|
return {tag: element.text.strip() if element.text else None}
|
|
623
|
+
|
|
331
624
|
root = ET.fromstring(xml_string)
|
|
625
|
+
|
|
332
626
|
return element_to_dict(root)
|
|
333
627
|
|
|
334
628
|
# end method definition
|
|
335
629
|
|
|
336
|
-
def find_key(self, data, target_key):
|
|
337
|
-
"""Recursively search for a key in a nested dictionary and return its value.
|
|
630
|
+
def find_key(self, data: dict | list, target_key: str) -> str:
|
|
631
|
+
"""Recursively search for a key in a nested dictionary and return its value.
|
|
632
|
+
|
|
633
|
+
Args:
|
|
634
|
+
data (dict | list):
|
|
635
|
+
TODO: _description_
|
|
636
|
+
target_key (str):
|
|
637
|
+
TODO: _description_
|
|
638
|
+
|
|
639
|
+
Returns:
|
|
640
|
+
_type_: _description_
|
|
641
|
+
|
|
642
|
+
"""
|
|
643
|
+
|
|
338
644
|
if isinstance(data, dict):
|
|
339
645
|
if target_key in data:
|
|
340
646
|
return data[target_key]
|
|
341
|
-
for
|
|
647
|
+
for value in data.values():
|
|
342
648
|
result = self.find_key(value, target_key)
|
|
343
649
|
if result is not None:
|
|
344
650
|
return result
|
|
@@ -347,6 +653,7 @@ class OTAWP:
|
|
|
347
653
|
result = self.find_key(item, target_key)
|
|
348
654
|
if result is not None:
|
|
349
655
|
return result
|
|
656
|
+
|
|
350
657
|
return None
|
|
351
658
|
|
|
352
659
|
# end method definition
|
|
@@ -357,20 +664,26 @@ class OTAWP:
|
|
|
357
664
|
additional_error_message: str = "",
|
|
358
665
|
show_error: bool = True,
|
|
359
666
|
) -> dict | None:
|
|
360
|
-
"""
|
|
361
|
-
|
|
667
|
+
"""Convert the text property of a request response object to a Python dict in a safe way.
|
|
668
|
+
|
|
669
|
+
Properly handle exceptions.
|
|
362
670
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
671
|
+
AppWorks may produce corrupt response when it gets restarted
|
|
672
|
+
or hitting resource limits. So we try to avoid a fatal error and bail
|
|
673
|
+
out more gracefully.
|
|
366
674
|
|
|
367
675
|
Args:
|
|
368
|
-
response_object (object):
|
|
369
|
-
|
|
370
|
-
|
|
676
|
+
response_object (object):
|
|
677
|
+
This is reponse object delivered by the request call.
|
|
678
|
+
additional_error_message (str):
|
|
679
|
+
Print a custom error message.
|
|
680
|
+
show_error (bool):
|
|
681
|
+
If True log an error, if False log a warning.
|
|
371
682
|
|
|
372
683
|
Returns:
|
|
373
|
-
dict:
|
|
684
|
+
dict:
|
|
685
|
+
Response or None in case of an error.
|
|
686
|
+
|
|
374
687
|
"""
|
|
375
688
|
|
|
376
689
|
if not response_object:
|
|
@@ -381,34 +694,39 @@ class OTAWP:
|
|
|
381
694
|
except json.JSONDecodeError as exception:
|
|
382
695
|
if additional_error_message:
|
|
383
696
|
message = "Cannot decode response as JSon. {}; error -> {}".format(
|
|
384
|
-
additional_error_message,
|
|
697
|
+
additional_error_message,
|
|
698
|
+
exception,
|
|
385
699
|
)
|
|
386
700
|
else:
|
|
387
701
|
message = "Cannot decode response as JSon; error -> {}".format(
|
|
388
|
-
exception
|
|
702
|
+
exception,
|
|
389
703
|
)
|
|
390
704
|
if show_error:
|
|
391
|
-
logger.error(message)
|
|
705
|
+
self.logger.error(message)
|
|
392
706
|
else:
|
|
393
|
-
logger.warning(message)
|
|
707
|
+
self.logger.warning(message)
|
|
394
708
|
return None
|
|
395
709
|
return dict_object
|
|
396
710
|
|
|
397
711
|
# end method definition
|
|
398
712
|
|
|
399
713
|
def authenticate(self, revalidate: bool = False) -> dict | None:
|
|
400
|
-
"""Authenticate at
|
|
714
|
+
"""Authenticate at AppWorks.
|
|
401
715
|
|
|
402
716
|
Args:
|
|
403
|
-
revalidate (bool, optional):
|
|
404
|
-
|
|
717
|
+
revalidate (bool, optional):
|
|
718
|
+
Determine if a re-authentication is enforced
|
|
719
|
+
(e.g. if session has timed out with 401 error).
|
|
720
|
+
|
|
405
721
|
Returns:
|
|
406
|
-
dict:
|
|
722
|
+
dict:
|
|
723
|
+
Cookie information. Also stores cookie information in self._cookie
|
|
724
|
+
|
|
407
725
|
"""
|
|
408
726
|
|
|
409
|
-
logger.info("SAMLart generation started")
|
|
727
|
+
self.logger.info("SAMLart generation started")
|
|
410
728
|
if self._cookie and not revalidate:
|
|
411
|
-
logger.
|
|
729
|
+
self.logger.debug(
|
|
412
730
|
"Session still valid - return existing cookie -> %s",
|
|
413
731
|
str(self._cookie),
|
|
414
732
|
)
|
|
@@ -423,30 +741,34 @@ class OTAWP:
|
|
|
423
741
|
url=self.credential_url(),
|
|
424
742
|
data=self.credentials(),
|
|
425
743
|
headers=REQUEST_HEADERS,
|
|
426
|
-
timeout=REQUEST_TIMEOUT
|
|
744
|
+
timeout=REQUEST_TIMEOUT,
|
|
427
745
|
)
|
|
428
746
|
except requests.exceptions.RequestException as exception:
|
|
429
|
-
logger.warning(
|
|
430
|
-
"Unable to connect to -> %s; error -> %s",
|
|
747
|
+
self.logger.warning(
|
|
748
|
+
"Unable to connect to OTAWP authentication endpoint -> %s; error -> %s",
|
|
431
749
|
self.credential_url(),
|
|
432
|
-
exception
|
|
750
|
+
str(exception),
|
|
433
751
|
)
|
|
434
|
-
logger.warning("OTAWP service may not be ready yet.")
|
|
752
|
+
self.logger.warning("OTAWP service may not be ready yet.")
|
|
435
753
|
return None
|
|
436
754
|
|
|
437
755
|
if response.ok:
|
|
438
|
-
logger.info("SAMLart generated successfully")
|
|
756
|
+
self.logger.info("SAMLart generated successfully")
|
|
439
757
|
authenticate_dict = self.parse_xml(response.text)
|
|
440
758
|
if not authenticate_dict:
|
|
441
759
|
return None
|
|
442
760
|
assertion_artifact_dict = self.find_key(
|
|
443
|
-
authenticate_dict,
|
|
761
|
+
authenticate_dict,
|
|
762
|
+
"AssertionArtifact",
|
|
444
763
|
)
|
|
445
764
|
if isinstance(assertion_artifact_dict, dict):
|
|
446
765
|
otawp_ticket = assertion_artifact_dict.get("AssertionArtifact")
|
|
447
|
-
logger.
|
|
766
|
+
self.logger.debug("SAML token -> %s", otawp_ticket)
|
|
448
767
|
else:
|
|
449
|
-
logger.error(
|
|
768
|
+
self.logger.error(
|
|
769
|
+
"Failed to request an OTAWP ticket; error -> %s",
|
|
770
|
+
response.text,
|
|
771
|
+
)
|
|
450
772
|
return None
|
|
451
773
|
|
|
452
774
|
self._cookie = {"defaultinst_SAMLart": otawp_ticket, "defaultinst_ct": "abcd"}
|
|
@@ -456,21 +778,23 @@ class OTAWP:
|
|
|
456
778
|
|
|
457
779
|
# end method definition
|
|
458
780
|
|
|
459
|
-
def create_workspace(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
workspace_id: str
|
|
463
|
-
) -> dict | None:
|
|
464
|
-
"""Creates a workspace in cws
|
|
781
|
+
def create_workspace(self, workspace_name: str, workspace_id: str) -> dict | None:
|
|
782
|
+
"""Create a workspace in cws.
|
|
783
|
+
|
|
465
784
|
Args:
|
|
466
|
-
workspace_name (str):
|
|
467
|
-
|
|
785
|
+
workspace_name (str):
|
|
786
|
+
The name of the workspace.
|
|
787
|
+
workspace_id (str):
|
|
788
|
+
The ID of the workspace.
|
|
789
|
+
|
|
468
790
|
Returns:
|
|
469
|
-
|
|
791
|
+
dict | None:
|
|
792
|
+
Response dictionary or error text
|
|
793
|
+
|
|
470
794
|
"""
|
|
471
795
|
|
|
472
|
-
logger.info(
|
|
473
|
-
"Create workspace
|
|
796
|
+
self.logger.info(
|
|
797
|
+
"Create workspace -> '%s' (%s)...",
|
|
474
798
|
workspace_name,
|
|
475
799
|
workspace_id,
|
|
476
800
|
)
|
|
@@ -567,10 +891,10 @@ class OTAWP:
|
|
|
567
891
|
data=license_post_body_json,
|
|
568
892
|
headers=REQUEST_HEADERS,
|
|
569
893
|
cookies=self.cookie(),
|
|
570
|
-
timeout=
|
|
894
|
+
timeout=REQUEST_TIMEOUT,
|
|
571
895
|
)
|
|
572
896
|
if response.ok:
|
|
573
|
-
logger.info(
|
|
897
|
+
self.logger.info(
|
|
574
898
|
"Successfully created workspace -> '%s' with ID -> %s",
|
|
575
899
|
workspace_name,
|
|
576
900
|
workspace_id,
|
|
@@ -578,69 +902,105 @@ class OTAWP:
|
|
|
578
902
|
return response.text
|
|
579
903
|
# Check if Session has expired - then re-authenticate and try once more
|
|
580
904
|
if response.status_code == 401 and retries == 0:
|
|
581
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
905
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
582
906
|
self.authenticate(revalidate=True)
|
|
583
907
|
retries += 1
|
|
584
|
-
logger.error(response.text)
|
|
908
|
+
self.logger.error(response.text)
|
|
585
909
|
return response.text
|
|
586
910
|
|
|
587
911
|
# end method definition
|
|
588
912
|
|
|
589
|
-
def sync_workspace(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
workspace_id: str
|
|
593
|
-
) -> dict | None:
|
|
594
|
-
""" sync workspaces
|
|
913
|
+
def sync_workspace(self, workspace_name: str, workspace_id: str) -> dict | None:
|
|
914
|
+
"""Synchronize workspace.
|
|
915
|
+
|
|
595
916
|
Args:
|
|
596
|
-
workspace_name (str):
|
|
597
|
-
|
|
917
|
+
workspace_name (str):
|
|
918
|
+
The name of the workspace.
|
|
919
|
+
workspace_id (str):
|
|
920
|
+
The ID of the workspace.
|
|
921
|
+
|
|
598
922
|
Returns:
|
|
599
|
-
|
|
923
|
+
dict | None:
|
|
924
|
+
Parsed response as a dictionary if successful, None otherwise.
|
|
925
|
+
|
|
600
926
|
"""
|
|
601
927
|
|
|
602
|
-
logger.info(
|
|
928
|
+
self.logger.info(
|
|
929
|
+
"Starting synchronization of workspace -> '%s'...",
|
|
930
|
+
workspace_name,
|
|
931
|
+
)
|
|
603
932
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
933
|
+
# SOAP request body
|
|
934
|
+
license_post_body_json = f"""
|
|
935
|
+
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
|
|
936
|
+
<SOAP:Body>
|
|
937
|
+
<Synchronize workspaceID="{workspace_id}" xmlns="http://schemas.cordys.com/cws/synchronize/1.0">
|
|
938
|
+
<DocumentID/>
|
|
939
|
+
<Asynchronous>false</Asynchronous>
|
|
940
|
+
</Synchronize>
|
|
941
|
+
</SOAP:Body>
|
|
942
|
+
</SOAP:Envelope>
|
|
943
|
+
"""
|
|
613
944
|
|
|
614
945
|
retries = 0
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
946
|
+
max_retries = 6
|
|
947
|
+
retry_delay = 60
|
|
948
|
+
|
|
949
|
+
while retries < max_retries:
|
|
950
|
+
try:
|
|
951
|
+
response = requests.post(
|
|
952
|
+
url=self.gateway_url(),
|
|
953
|
+
data=license_post_body_json,
|
|
954
|
+
headers=REQUEST_HEADERS,
|
|
955
|
+
cookies=self.cookie(),
|
|
956
|
+
timeout=SYNC_PUBLISH_REQUEST_TIMEOUT,
|
|
957
|
+
)
|
|
958
|
+
|
|
959
|
+
if response.ok:
|
|
960
|
+
self.logger.info(
|
|
961
|
+
"Workspace -> '%s' synchronized successfully.",
|
|
962
|
+
workspace_name,
|
|
963
|
+
)
|
|
964
|
+
return self.parse_xml(response.text)
|
|
965
|
+
|
|
966
|
+
if response.status_code == 401:
|
|
967
|
+
self.logger.warning("Session expired. Re-authenticating...")
|
|
968
|
+
self.authenticate(revalidate=True)
|
|
969
|
+
retries += 1
|
|
970
|
+
continue
|
|
971
|
+
|
|
972
|
+
if "faultcode" in response.text or "FaultDetails" in response.text:
|
|
973
|
+
self.logger.warning("SOAP fault occurred: %s", response.text)
|
|
974
|
+
retries += 1
|
|
975
|
+
time.sleep(retry_delay)
|
|
976
|
+
continue
|
|
977
|
+
|
|
978
|
+
self.logger.error("Unexpected error during sync: %s", response.text)
|
|
979
|
+
time.sleep(retry_delay)
|
|
629
980
|
retries += 1
|
|
630
|
-
|
|
631
|
-
|
|
981
|
+
|
|
982
|
+
except requests.RequestException:
|
|
983
|
+
self.logger.error("Sync failed with error. Proceeding with retry...")
|
|
984
|
+
time.sleep(retry_delay)
|
|
985
|
+
retries += 1
|
|
986
|
+
|
|
987
|
+
self.logger.error(
|
|
988
|
+
"Synchronization failed for workspace -> '%s' after %d retries.",
|
|
989
|
+
workspace_name,
|
|
990
|
+
retries,
|
|
991
|
+
)
|
|
992
|
+
return None
|
|
632
993
|
|
|
633
994
|
# end method definition
|
|
634
995
|
|
|
635
996
|
def publish_project(
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
"""
|
|
643
|
-
Publish the workspace project.
|
|
997
|
+
self,
|
|
998
|
+
workspace_name: str,
|
|
999
|
+
project_name: str,
|
|
1000
|
+
workspace_id: str,
|
|
1001
|
+
project_id: str,
|
|
1002
|
+
) -> dict | bool:
|
|
1003
|
+
"""Publish the workspace project.
|
|
644
1004
|
|
|
645
1005
|
Args:
|
|
646
1006
|
workspace_name (str): The name of the workspace.
|
|
@@ -650,9 +1010,10 @@ class OTAWP:
|
|
|
650
1010
|
|
|
651
1011
|
Returns:
|
|
652
1012
|
dict | bool: Request response (dictionary) if successful, False if it fails after retries.
|
|
1013
|
+
|
|
653
1014
|
"""
|
|
654
1015
|
|
|
655
|
-
logger.info(
|
|
1016
|
+
self.logger.info(
|
|
656
1017
|
"Publish project -> '%s' in workspace -> '%s'...",
|
|
657
1018
|
project_name,
|
|
658
1019
|
workspace_name,
|
|
@@ -674,54 +1035,57 @@ class OTAWP:
|
|
|
674
1035
|
success_indicator = "deployObjectResponse"
|
|
675
1036
|
|
|
676
1037
|
while retries < max_retries:
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
1038
|
+
try:
|
|
1039
|
+
response = requests.post(
|
|
1040
|
+
url=self.gateway_url(),
|
|
1041
|
+
data=project_publish,
|
|
1042
|
+
headers=REQUEST_HEADERS,
|
|
1043
|
+
cookies=self.cookie(),
|
|
1044
|
+
timeout=SYNC_PUBLISH_REQUEST_TIMEOUT,
|
|
1045
|
+
)
|
|
684
1046
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
1047
|
+
# Check if the response is successful
|
|
1048
|
+
if response.ok:
|
|
1049
|
+
if success_indicator in response.text:
|
|
1050
|
+
self.logger.info(
|
|
1051
|
+
"Successfully published project -> '%s' in workspace -> '%s'",
|
|
1052
|
+
project_name,
|
|
1053
|
+
workspace_name,
|
|
1054
|
+
)
|
|
1055
|
+
return True
|
|
1056
|
+
else:
|
|
1057
|
+
self.logger.warning(
|
|
1058
|
+
"Expected success indicator -> '%s' but it was not found in response. Retrying in 30 seconds... (Attempt %d of %d)",
|
|
1059
|
+
success_indicator,
|
|
1060
|
+
retries + 1,
|
|
1061
|
+
max_retries,
|
|
1062
|
+
)
|
|
1063
|
+
elif response.status_code == 401:
|
|
1064
|
+
# Check for session expiry and retry authentication
|
|
1065
|
+
self.logger.warning("Session has expired - re-authenticating...")
|
|
1066
|
+
self.authenticate(revalidate=True)
|
|
1067
|
+
else:
|
|
1068
|
+
self.logger.error(
|
|
1069
|
+
"Unexpected error (status code %d). Retrying in 30 seconds... (Attempt %d of %d)",
|
|
1070
|
+
response.status_code,
|
|
1071
|
+
retries + 1,
|
|
1072
|
+
max_retries,
|
|
693
1073
|
)
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
success_indicator,
|
|
700
|
-
retries + 1,
|
|
701
|
-
max_retries,
|
|
702
|
-
)
|
|
703
|
-
time.sleep(30)
|
|
1074
|
+
self.logger.error(
|
|
1075
|
+
"Error details: %s",
|
|
1076
|
+
response.text,
|
|
1077
|
+
)
|
|
1078
|
+
self.sync_workspace(workspace_name, workspace_id)
|
|
704
1079
|
retries += 1
|
|
705
|
-
|
|
1080
|
+
time.sleep(30)
|
|
706
1081
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
logger.warning("Session has expired - re-authenticating...")
|
|
710
|
-
self.authenticate(revalidate=True)
|
|
1082
|
+
except requests.RequestException:
|
|
1083
|
+
self.logger.error("Sync failed with error. Proceeding with retry...")
|
|
711
1084
|
retries += 1
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
# Log any other error and break the loop
|
|
715
|
-
logger.error(
|
|
716
|
-
"Error publishing project -> '%s' in workspace -> '%s'; response -> %s",
|
|
717
|
-
project_name,
|
|
718
|
-
workspace_name,
|
|
719
|
-
response.text,
|
|
720
|
-
)
|
|
721
|
-
break
|
|
1085
|
+
time.sleep(30)
|
|
722
1086
|
|
|
723
1087
|
# After reaching the maximum number of retries, log failure and return False
|
|
724
|
-
logger.error(
|
|
1088
|
+
self.logger.error(
|
|
725
1089
|
"Max retries reached. Failed to publish project -> '%s' in workspace -> '%s'.",
|
|
726
1090
|
project_name,
|
|
727
1091
|
workspace_name,
|
|
@@ -730,27 +1094,21 @@ class OTAWP:
|
|
|
730
1094
|
|
|
731
1095
|
# end method definition
|
|
732
1096
|
|
|
733
|
-
def create_priority(
|
|
734
|
-
|
|
735
|
-
name: str,
|
|
736
|
-
description: str,
|
|
737
|
-
status: int
|
|
738
|
-
) -> dict | None:
|
|
739
|
-
""" Create Priority entity instances.
|
|
1097
|
+
def create_priority(self, name: str, description: str, status: int) -> dict | None:
|
|
1098
|
+
"""Create Priority entity instances.
|
|
740
1099
|
|
|
741
1100
|
Args:
|
|
742
1101
|
name (str): name
|
|
743
1102
|
description (str): description
|
|
744
1103
|
status (int): status
|
|
1104
|
+
|
|
745
1105
|
Returns:
|
|
746
|
-
dict:
|
|
1106
|
+
dict:
|
|
1107
|
+
Request response (dictionary) or None if the REST call fails
|
|
1108
|
+
|
|
747
1109
|
"""
|
|
748
1110
|
create_priority = {
|
|
749
|
-
"Properties": {
|
|
750
|
-
"Name": name,
|
|
751
|
-
"Description": description,
|
|
752
|
-
"Status": status
|
|
753
|
-
}
|
|
1111
|
+
"Properties": {"Name": name, "Description": description, "Status": status},
|
|
754
1112
|
}
|
|
755
1113
|
retries = 0
|
|
756
1114
|
while True:
|
|
@@ -759,51 +1117,58 @@ class OTAWP:
|
|
|
759
1117
|
json=create_priority,
|
|
760
1118
|
headers=REQUEST_HEADERS_JSON,
|
|
761
1119
|
cookies=self.cookie(),
|
|
762
|
-
timeout=
|
|
1120
|
+
timeout=REQUEST_TIMEOUT,
|
|
763
1121
|
)
|
|
764
1122
|
if response.ok:
|
|
765
|
-
logger.info("Priority created successfully")
|
|
1123
|
+
self.logger.info("Priority created successfully")
|
|
766
1124
|
return self.parse_request_response(
|
|
767
|
-
response,
|
|
1125
|
+
response_object=response,
|
|
1126
|
+
additional_error_message="This can be normal during restart",
|
|
1127
|
+
show_error=False,
|
|
768
1128
|
)
|
|
769
1129
|
if response.status_code == 401 and retries == 0:
|
|
770
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1130
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
771
1131
|
self.authenticate(revalidate=True)
|
|
772
1132
|
retries += 1
|
|
773
|
-
logger.error(response.text)
|
|
1133
|
+
self.logger.error(response.text)
|
|
774
1134
|
return None
|
|
775
1135
|
|
|
776
1136
|
# end method definition
|
|
777
1137
|
|
|
778
|
-
def get_all_priorities(
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
""" Get all priorities from entity
|
|
1138
|
+
def get_all_priorities(self) -> dict | None:
|
|
1139
|
+
"""Get all priorities from entity.
|
|
1140
|
+
|
|
782
1141
|
Args:
|
|
783
1142
|
None
|
|
1143
|
+
|
|
784
1144
|
Returns:
|
|
785
|
-
dict:
|
|
1145
|
+
dict:
|
|
1146
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1147
|
+
|
|
786
1148
|
"""
|
|
1149
|
+
|
|
787
1150
|
retries = 0
|
|
788
1151
|
while True:
|
|
789
1152
|
response = requests.get(
|
|
790
1153
|
url=self.get_all_priorities_url(),
|
|
791
1154
|
headers=REQUEST_HEADERS_JSON,
|
|
792
1155
|
cookies=self.cookie(),
|
|
793
|
-
timeout=
|
|
1156
|
+
timeout=REQUEST_TIMEOUT,
|
|
794
1157
|
)
|
|
795
1158
|
if response.ok:
|
|
796
1159
|
authenticate_dict = self.parse_request_response(
|
|
797
|
-
|
|
1160
|
+
response_object=response,
|
|
1161
|
+
additional_error_message="This can be normal during restart",
|
|
1162
|
+
show_error=False,
|
|
798
1163
|
)
|
|
799
1164
|
if not authenticate_dict:
|
|
800
1165
|
return None
|
|
801
1166
|
return authenticate_dict
|
|
802
1167
|
if response.status_code == 401 and retries == 0:
|
|
803
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1168
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
804
1169
|
self.authenticate(revalidate=True)
|
|
805
1170
|
retries += 1
|
|
806
|
-
logger.error(response.text)
|
|
1171
|
+
self.logger.error(response.text)
|
|
807
1172
|
return None
|
|
808
1173
|
|
|
809
1174
|
# end method definition
|
|
@@ -812,23 +1177,30 @@ class OTAWP:
|
|
|
812
1177
|
self,
|
|
813
1178
|
customer_name: str,
|
|
814
1179
|
legal_business_name: str,
|
|
815
|
-
trading_name: str
|
|
1180
|
+
trading_name: str,
|
|
816
1181
|
) -> dict | None:
|
|
817
|
-
"""
|
|
1182
|
+
"""Create customer entity instance.
|
|
818
1183
|
|
|
819
1184
|
Args:
|
|
820
|
-
customer_name (str):
|
|
821
|
-
|
|
822
|
-
|
|
1185
|
+
customer_name (str):
|
|
1186
|
+
The name of the customer.
|
|
1187
|
+
legal_business_name (str):
|
|
1188
|
+
The legal business name.
|
|
1189
|
+
trading_name (str):
|
|
1190
|
+
The trading name.
|
|
1191
|
+
|
|
823
1192
|
Returns:
|
|
824
|
-
dict:
|
|
1193
|
+
dict:
|
|
1194
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1195
|
+
|
|
825
1196
|
"""
|
|
1197
|
+
|
|
826
1198
|
create_customer = {
|
|
827
1199
|
"Properties": {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
}
|
|
1200
|
+
"CustomerName": customer_name,
|
|
1201
|
+
"LegalBusinessName": legal_business_name,
|
|
1202
|
+
"TradingName": trading_name,
|
|
1203
|
+
},
|
|
832
1204
|
}
|
|
833
1205
|
retries = 0
|
|
834
1206
|
while True:
|
|
@@ -837,29 +1209,34 @@ class OTAWP:
|
|
|
837
1209
|
json=create_customer,
|
|
838
1210
|
headers=REQUEST_HEADERS_JSON,
|
|
839
1211
|
cookies=self.cookie(),
|
|
840
|
-
timeout=
|
|
1212
|
+
timeout=REQUEST_TIMEOUT,
|
|
841
1213
|
)
|
|
842
1214
|
if response.ok:
|
|
843
|
-
logger.info("Customer record created successfully")
|
|
844
|
-
return
|
|
1215
|
+
self.logger.info("Customer record created successfully")
|
|
1216
|
+
return self.parse_request_response(
|
|
1217
|
+
response_object=response,
|
|
1218
|
+
additional_error_message="This can be normal during restart",
|
|
1219
|
+
show_error=False,
|
|
1220
|
+
)
|
|
845
1221
|
if response.status_code == 401 and retries == 0:
|
|
846
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1222
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
847
1223
|
self.authenticate(revalidate=True)
|
|
848
1224
|
retries += 1
|
|
849
|
-
logger.error(response.text)
|
|
1225
|
+
self.logger.error(response.text)
|
|
850
1226
|
return None
|
|
851
1227
|
|
|
852
1228
|
# end method definition
|
|
853
1229
|
|
|
854
|
-
def get_all_customers(
|
|
855
|
-
|
|
856
|
-
) -> dict | None:
|
|
857
|
-
"""get all customer entity imstances
|
|
1230
|
+
def get_all_customers(self) -> dict | None:
|
|
1231
|
+
"""Get all customer entity imstances.
|
|
858
1232
|
|
|
859
1233
|
Args:
|
|
860
1234
|
None
|
|
1235
|
+
|
|
861
1236
|
Returns:
|
|
862
|
-
dict:
|
|
1237
|
+
dict:
|
|
1238
|
+
Request response (dictionary) or None if the REST call fails
|
|
1239
|
+
|
|
863
1240
|
"""
|
|
864
1241
|
|
|
865
1242
|
retries = 0
|
|
@@ -868,45 +1245,44 @@ class OTAWP:
|
|
|
868
1245
|
url=self.get_all_customeres_url(),
|
|
869
1246
|
headers=REQUEST_HEADERS_JSON,
|
|
870
1247
|
cookies=self.cookie(),
|
|
871
|
-
timeout=
|
|
1248
|
+
timeout=REQUEST_TIMEOUT,
|
|
872
1249
|
)
|
|
873
1250
|
if response.ok:
|
|
874
1251
|
authenticate_dict = self.parse_request_response(
|
|
875
|
-
|
|
1252
|
+
response_object=response,
|
|
1253
|
+
additional_error_message="This can be normal during restart",
|
|
1254
|
+
show_error=False,
|
|
876
1255
|
)
|
|
877
1256
|
if not authenticate_dict:
|
|
878
1257
|
return None
|
|
879
|
-
return
|
|
1258
|
+
return authenticate_dict
|
|
880
1259
|
if response.status_code == 401 and retries == 0:
|
|
881
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1260
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
882
1261
|
self.authenticate(revalidate=True)
|
|
883
1262
|
retries += 1
|
|
884
|
-
logger.error(response.text)
|
|
1263
|
+
self.logger.error(response.text)
|
|
885
1264
|
return None
|
|
886
1265
|
|
|
887
1266
|
# end method definition
|
|
888
1267
|
|
|
889
|
-
def create_case_type(
|
|
890
|
-
|
|
891
|
-
name: str,
|
|
892
|
-
description: str,
|
|
893
|
-
status: int
|
|
894
|
-
) -> dict | None:
|
|
895
|
-
"""create case_type entity instances
|
|
1268
|
+
def create_case_type(self, name: str, description: str, status: int) -> dict | None:
|
|
1269
|
+
"""Create case type entity instances.
|
|
896
1270
|
|
|
897
1271
|
Args:
|
|
898
|
-
name (str):
|
|
899
|
-
|
|
1272
|
+
name (str):
|
|
1273
|
+
The name of the case type.
|
|
1274
|
+
description (str):
|
|
1275
|
+
The description of the case type.
|
|
900
1276
|
status (str): status
|
|
1277
|
+
|
|
901
1278
|
Returns:
|
|
902
|
-
dict:
|
|
1279
|
+
dict:
|
|
1280
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1281
|
+
|
|
903
1282
|
"""
|
|
1283
|
+
|
|
904
1284
|
create_case_type = {
|
|
905
|
-
"Properties": {
|
|
906
|
-
"Name": name,
|
|
907
|
-
"Description": description,
|
|
908
|
-
"Status": status
|
|
909
|
-
}
|
|
1285
|
+
"Properties": {"Name": name, "Description": description, "Status": status},
|
|
910
1286
|
}
|
|
911
1287
|
retries = 0
|
|
912
1288
|
while True:
|
|
@@ -915,52 +1291,58 @@ class OTAWP:
|
|
|
915
1291
|
json=create_case_type,
|
|
916
1292
|
headers=REQUEST_HEADERS_JSON,
|
|
917
1293
|
cookies=self.cookie(),
|
|
918
|
-
timeout=
|
|
1294
|
+
timeout=REQUEST_TIMEOUT,
|
|
919
1295
|
)
|
|
920
1296
|
if response.ok:
|
|
921
|
-
logger.info("Case type created successfully")
|
|
1297
|
+
self.logger.info("Case type created successfully")
|
|
922
1298
|
return self.parse_request_response(
|
|
923
|
-
response,
|
|
1299
|
+
response_object=response,
|
|
1300
|
+
additional_error_message="This can be normal during restart",
|
|
1301
|
+
show_error=False,
|
|
924
1302
|
)
|
|
925
1303
|
if response.status_code == 401 and retries == 0:
|
|
926
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1304
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
927
1305
|
self.authenticate(revalidate=True)
|
|
928
1306
|
retries += 1
|
|
929
|
-
logger.error(response.text)
|
|
1307
|
+
self.logger.error(response.text)
|
|
930
1308
|
return None
|
|
931
1309
|
|
|
932
1310
|
# end method definition
|
|
933
1311
|
|
|
934
|
-
def get_all_case_type(
|
|
935
|
-
|
|
936
|
-
) -> dict | None:
|
|
937
|
-
"""get all case type entty instances
|
|
1312
|
+
def get_all_case_type(self) -> dict | None:
|
|
1313
|
+
"""Get all case type entty instances.
|
|
938
1314
|
|
|
939
1315
|
Args:
|
|
940
1316
|
None
|
|
1317
|
+
|
|
941
1318
|
Returns:
|
|
942
|
-
dict:
|
|
1319
|
+
dict:
|
|
1320
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1321
|
+
|
|
943
1322
|
"""
|
|
1323
|
+
|
|
944
1324
|
retries = 0
|
|
945
1325
|
while True:
|
|
946
1326
|
response = requests.get(
|
|
947
1327
|
url=self.get_all_case_types_url(),
|
|
948
1328
|
headers=REQUEST_HEADERS_JSON,
|
|
949
1329
|
cookies=self.cookie(),
|
|
950
|
-
timeout=
|
|
1330
|
+
timeout=REQUEST_TIMEOUT,
|
|
951
1331
|
)
|
|
952
1332
|
if response.ok:
|
|
953
1333
|
authenticate_dict = self.parse_request_response(
|
|
954
|
-
|
|
1334
|
+
response_object=response,
|
|
1335
|
+
additional_error_message="This can be normal during restart",
|
|
1336
|
+
show_error=False,
|
|
955
1337
|
)
|
|
956
1338
|
if not authenticate_dict:
|
|
957
1339
|
return None
|
|
958
1340
|
return authenticate_dict
|
|
959
1341
|
if response.status_code == 401 and retries == 0:
|
|
960
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1342
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
961
1343
|
self.authenticate(revalidate=True)
|
|
962
1344
|
retries += 1
|
|
963
|
-
logger.error(response.text)
|
|
1345
|
+
self.logger.error(response.text)
|
|
964
1346
|
return None
|
|
965
1347
|
|
|
966
1348
|
# end method definition
|
|
@@ -970,25 +1352,33 @@ class OTAWP:
|
|
|
970
1352
|
case_prefix: str,
|
|
971
1353
|
description: str,
|
|
972
1354
|
name: str,
|
|
973
|
-
status: int
|
|
1355
|
+
status: int,
|
|
974
1356
|
) -> dict | None:
|
|
975
|
-
"""
|
|
1357
|
+
"""Create category entity instance.
|
|
976
1358
|
|
|
977
1359
|
Args:
|
|
978
|
-
case_prefix (str):
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1360
|
+
case_prefix (str):
|
|
1361
|
+
The prefix for the case.
|
|
1362
|
+
description (str):
|
|
1363
|
+
The description for the category.
|
|
1364
|
+
name (str):
|
|
1365
|
+
The name of the case.
|
|
1366
|
+
status (int):
|
|
1367
|
+
The status code.
|
|
1368
|
+
|
|
982
1369
|
Returns:
|
|
983
|
-
dict:
|
|
1370
|
+
dict:
|
|
1371
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1372
|
+
|
|
984
1373
|
"""
|
|
1374
|
+
|
|
985
1375
|
create_categoty = {
|
|
986
1376
|
"Properties": {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
}
|
|
1377
|
+
"CasePrefix": case_prefix,
|
|
1378
|
+
"Description": description,
|
|
1379
|
+
"Name": name,
|
|
1380
|
+
"Status": status,
|
|
1381
|
+
},
|
|
992
1382
|
}
|
|
993
1383
|
retries = 0
|
|
994
1384
|
while True:
|
|
@@ -997,29 +1387,33 @@ class OTAWP:
|
|
|
997
1387
|
json=create_categoty,
|
|
998
1388
|
headers=REQUEST_HEADERS_JSON,
|
|
999
1389
|
cookies=self.cookie(),
|
|
1000
|
-
timeout=
|
|
1390
|
+
timeout=REQUEST_TIMEOUT,
|
|
1001
1391
|
)
|
|
1002
1392
|
if response.ok:
|
|
1003
|
-
logger.info("Category created successfully")
|
|
1004
|
-
return
|
|
1393
|
+
self.logger.info("Category created successfully")
|
|
1394
|
+
return self.parse_request_response(
|
|
1395
|
+
response_object=response,
|
|
1396
|
+
additional_error_message="This can be normal during restart",
|
|
1397
|
+
show_error=False,
|
|
1398
|
+
)
|
|
1005
1399
|
if response.status_code == 401 and retries == 0:
|
|
1006
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1400
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
1007
1401
|
self.authenticate(revalidate=True)
|
|
1008
1402
|
retries += 1
|
|
1009
|
-
logger.error(response.text)
|
|
1403
|
+
self.logger.error(response.text)
|
|
1010
1404
|
return None
|
|
1011
1405
|
|
|
1012
1406
|
# end method definition
|
|
1013
1407
|
|
|
1014
|
-
def get_all_categories(
|
|
1015
|
-
|
|
1016
|
-
) -> dict | None:
|
|
1017
|
-
"""Get all categories entity intances
|
|
1408
|
+
def get_all_categories(self) -> dict | None:
|
|
1409
|
+
"""Get all categories entity intances.
|
|
1018
1410
|
|
|
1019
1411
|
Args:
|
|
1020
1412
|
None
|
|
1021
1413
|
Returns:
|
|
1022
|
-
dict:
|
|
1414
|
+
dict:
|
|
1415
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1416
|
+
|
|
1023
1417
|
"""
|
|
1024
1418
|
|
|
1025
1419
|
retries = 0
|
|
@@ -1028,20 +1422,22 @@ class OTAWP:
|
|
|
1028
1422
|
url=self.get_all_categories_url(),
|
|
1029
1423
|
headers=REQUEST_HEADERS_JSON,
|
|
1030
1424
|
cookies=self.cookie(),
|
|
1031
|
-
timeout=
|
|
1425
|
+
timeout=REQUEST_TIMEOUT,
|
|
1032
1426
|
)
|
|
1033
1427
|
if response.ok:
|
|
1034
1428
|
authenticate_dict = self.parse_request_response(
|
|
1035
|
-
|
|
1429
|
+
response_object=response,
|
|
1430
|
+
additional_error_message="This can be normal during restart",
|
|
1431
|
+
show_error=False,
|
|
1036
1432
|
)
|
|
1037
1433
|
if not authenticate_dict:
|
|
1038
1434
|
return None
|
|
1039
|
-
return
|
|
1435
|
+
return authenticate_dict
|
|
1040
1436
|
if response.status_code == 401 and retries == 0:
|
|
1041
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1437
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
1042
1438
|
self.authenticate(revalidate=True)
|
|
1043
1439
|
retries += 1
|
|
1044
|
-
logger.error(response.text)
|
|
1440
|
+
self.logger.error(response.text)
|
|
1045
1441
|
return None
|
|
1046
1442
|
|
|
1047
1443
|
# end method definition
|
|
@@ -1051,24 +1447,28 @@ class OTAWP:
|
|
|
1051
1447
|
name: str,
|
|
1052
1448
|
description: str,
|
|
1053
1449
|
status: int,
|
|
1054
|
-
|
|
1450
|
+
parent_id: int,
|
|
1055
1451
|
) -> dict | None:
|
|
1056
|
-
"""
|
|
1452
|
+
"""Create sub categoy entity instances.
|
|
1057
1453
|
|
|
1058
1454
|
Args:
|
|
1059
|
-
name (str):
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1455
|
+
name (str):
|
|
1456
|
+
The name of the sub-category.
|
|
1457
|
+
description (str):
|
|
1458
|
+
The description for the sub-category.
|
|
1459
|
+
status (int):
|
|
1460
|
+
The status ID.
|
|
1461
|
+
parent_id (int):
|
|
1462
|
+
The parent ID of the category.
|
|
1463
|
+
|
|
1063
1464
|
Returns:
|
|
1064
|
-
dict:
|
|
1465
|
+
dict:
|
|
1466
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1467
|
+
|
|
1065
1468
|
"""
|
|
1469
|
+
|
|
1066
1470
|
create_sub_categoty = {
|
|
1067
|
-
"Properties": {
|
|
1068
|
-
"Name": name,
|
|
1069
|
-
"Description": description,
|
|
1070
|
-
"Status": status
|
|
1071
|
-
}
|
|
1471
|
+
"Properties": {"Name": name, "Description": description, "Status": status},
|
|
1072
1472
|
}
|
|
1073
1473
|
retries = 0
|
|
1074
1474
|
while True:
|
|
@@ -1076,60 +1476,66 @@ class OTAWP:
|
|
|
1076
1476
|
endpoint = "/app/entityRestService/api/OpentextCaseManagement/entities/Category/items/"
|
|
1077
1477
|
child_path = "/childEntities/SubCategory?defaultinst_ct=abcd"
|
|
1078
1478
|
response = requests.post(
|
|
1079
|
-
url=base_url + endpoint + str(
|
|
1479
|
+
url=base_url + endpoint + str(parent_id) + child_path,
|
|
1080
1480
|
json=create_sub_categoty,
|
|
1081
1481
|
headers=REQUEST_HEADERS_JSON,
|
|
1082
1482
|
cookies=self.cookie(),
|
|
1083
|
-
timeout=
|
|
1483
|
+
timeout=REQUEST_TIMEOUT,
|
|
1084
1484
|
)
|
|
1085
1485
|
if response.ok:
|
|
1086
|
-
logger.info("Sub category created successfully")
|
|
1486
|
+
self.logger.info("Sub category created successfully")
|
|
1087
1487
|
return self.parse_request_response(
|
|
1088
|
-
response,
|
|
1488
|
+
response_object=response,
|
|
1489
|
+
additional_error_message="This can be normal during restart",
|
|
1490
|
+
show_error=False,
|
|
1089
1491
|
)
|
|
1090
1492
|
if response.status_code == 401 and retries == 0:
|
|
1091
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1493
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
1092
1494
|
self.authenticate(revalidate=True)
|
|
1093
1495
|
retries += 1
|
|
1094
|
-
logger.error(response.text)
|
|
1496
|
+
self.logger.error(response.text)
|
|
1095
1497
|
return None
|
|
1096
1498
|
|
|
1097
1499
|
# end method definition
|
|
1098
1500
|
|
|
1099
|
-
def get_all_sub_categeries(
|
|
1100
|
-
|
|
1101
|
-
parentid: int
|
|
1102
|
-
) -> dict | None:
|
|
1103
|
-
"""Get all sub categeries entity instances
|
|
1501
|
+
def get_all_sub_categeries(self, parent_id: int) -> dict | None:
|
|
1502
|
+
"""Get all sub categeries entity instances.
|
|
1104
1503
|
|
|
1105
1504
|
Args:
|
|
1106
|
-
|
|
1505
|
+
parent_id (int):
|
|
1506
|
+
The parent ID of the sub categories.
|
|
1507
|
+
|
|
1107
1508
|
Returns:
|
|
1108
|
-
dict:
|
|
1509
|
+
dict:
|
|
1510
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1511
|
+
|
|
1109
1512
|
"""
|
|
1513
|
+
|
|
1110
1514
|
retries = 0
|
|
1111
1515
|
while True:
|
|
1112
1516
|
base_url = self.baseurl()
|
|
1113
1517
|
endpoint = "/app/entityRestService/api/OpentextCaseManagement/entities/Category/items/"
|
|
1114
1518
|
child_path = "/childEntities/SubCategory"
|
|
1115
1519
|
response = requests.get(
|
|
1116
|
-
url=base_url + endpoint + str(
|
|
1520
|
+
url=base_url + endpoint + str(parent_id) + child_path,
|
|
1117
1521
|
headers=REQUEST_HEADERS_JSON,
|
|
1118
1522
|
cookies=self.cookie(),
|
|
1119
|
-
timeout=
|
|
1523
|
+
timeout=REQUEST_TIMEOUT,
|
|
1120
1524
|
)
|
|
1121
1525
|
if response.ok:
|
|
1122
1526
|
authenticate_dict = self.parse_request_response(
|
|
1123
|
-
|
|
1527
|
+
response_object=response,
|
|
1528
|
+
additional_error_message="This can be normal during restart",
|
|
1529
|
+
show_error=False,
|
|
1124
1530
|
)
|
|
1125
1531
|
if not authenticate_dict:
|
|
1126
1532
|
return None
|
|
1127
|
-
return
|
|
1533
|
+
return authenticate_dict
|
|
1128
1534
|
if response.status_code == 401 and retries == 0:
|
|
1129
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1535
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
1130
1536
|
self.authenticate(revalidate=True)
|
|
1131
1537
|
retries += 1
|
|
1132
|
-
logger.error(response.text)
|
|
1538
|
+
self.logger.error(response.text)
|
|
1133
1539
|
return None
|
|
1134
1540
|
|
|
1135
1541
|
# end method definition
|
|
@@ -1142,12 +1548,11 @@ class OTAWP:
|
|
|
1142
1548
|
loan_duration_in_months: str,
|
|
1143
1549
|
category: str,
|
|
1144
1550
|
subcategory: str,
|
|
1145
|
-
|
|
1551
|
+
priority: str,
|
|
1146
1552
|
service: str,
|
|
1147
|
-
customer: str
|
|
1148
|
-
|
|
1553
|
+
customer: str,
|
|
1149
1554
|
) -> dict | None:
|
|
1150
|
-
"""
|
|
1555
|
+
"""Create loan entity instance.
|
|
1151
1556
|
|
|
1152
1557
|
Args:
|
|
1153
1558
|
subject (str): subject
|
|
@@ -1156,12 +1561,14 @@ class OTAWP:
|
|
|
1156
1561
|
loan_duration_in_months (str): loan_duration_in_months
|
|
1157
1562
|
category (str): category
|
|
1158
1563
|
subcategory (str): subcategory
|
|
1159
|
-
|
|
1564
|
+
priority (str): priority
|
|
1160
1565
|
service (str): service
|
|
1161
1566
|
customer (str): customer
|
|
1162
1567
|
Returns:
|
|
1163
1568
|
dict: Request response (dictionary) or None if the REST call fails
|
|
1569
|
+
|
|
1164
1570
|
"""
|
|
1571
|
+
|
|
1165
1572
|
create_loan = f"""<SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n
|
|
1166
1573
|
<SOAP:Body>\r\n
|
|
1167
1574
|
<CreateCase xmlns=\"http://schemas/OpentextCaseManagement/Case/operations\">\r\n
|
|
@@ -1192,7 +1599,7 @@ class OTAWP:
|
|
|
1192
1599
|
\r\n
|
|
1193
1600
|
<ns0:Priority>\r\n
|
|
1194
1601
|
<ns3:Priority-id xmlns:ns3=\"http://schemas/OpentextCaseManagement/Priority\">\r\n
|
|
1195
|
-
<ns3:Id>{
|
|
1602
|
+
<ns3:Id>{priority}</ns3:Id>\r\n
|
|
1196
1603
|
</ns3:Priority-id>\r\n
|
|
1197
1604
|
</ns0:Priority>\r\n
|
|
1198
1605
|
\r\n
|
|
@@ -1214,29 +1621,30 @@ class OTAWP:
|
|
|
1214
1621
|
data=create_loan,
|
|
1215
1622
|
headers=REQUEST_HEADERS,
|
|
1216
1623
|
cookies=self.cookie(),
|
|
1217
|
-
timeout=
|
|
1624
|
+
timeout=REQUEST_TIMEOUT,
|
|
1218
1625
|
)
|
|
1219
1626
|
if response.ok:
|
|
1220
|
-
logger.info("Loan created successfully")
|
|
1221
|
-
return
|
|
1627
|
+
self.logger.info("Loan created successfully")
|
|
1628
|
+
return self.parse_xml(response.text)
|
|
1222
1629
|
if response.status_code == 401 and retries == 0:
|
|
1223
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1630
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
1224
1631
|
self.authenticate(revalidate=True)
|
|
1225
1632
|
retries += 1
|
|
1226
|
-
logger.error(response.text)
|
|
1633
|
+
self.logger.error(response.text)
|
|
1227
1634
|
return None
|
|
1228
1635
|
|
|
1229
1636
|
# end method definition
|
|
1230
1637
|
|
|
1231
|
-
def get_all_loan(
|
|
1232
|
-
|
|
1233
|
-
) -> dict | None:
|
|
1234
|
-
"""get all loan entity instances
|
|
1638
|
+
def get_all_loan(self) -> dict | None:
|
|
1639
|
+
"""Get all loan entity instances.
|
|
1235
1640
|
|
|
1236
1641
|
Args:
|
|
1237
1642
|
None
|
|
1643
|
+
|
|
1238
1644
|
Returns:
|
|
1239
|
-
dict:
|
|
1645
|
+
dict:
|
|
1646
|
+
Request response (dictionary) or None if the REST call fails.
|
|
1647
|
+
|
|
1240
1648
|
"""
|
|
1241
1649
|
|
|
1242
1650
|
retries = 0
|
|
@@ -1245,32 +1653,29 @@ class OTAWP:
|
|
|
1245
1653
|
url=self.get_all_loans_url(),
|
|
1246
1654
|
headers=REQUEST_HEADERS_JSON,
|
|
1247
1655
|
cookies=self.cookie(),
|
|
1248
|
-
timeout=
|
|
1656
|
+
timeout=REQUEST_TIMEOUT,
|
|
1249
1657
|
)
|
|
1250
1658
|
if response.ok:
|
|
1251
1659
|
authenticate_dict = self.parse_request_response(
|
|
1252
|
-
|
|
1660
|
+
response_object=response,
|
|
1661
|
+
additional_error_message="This can be normal during restart",
|
|
1662
|
+
show_error=False,
|
|
1253
1663
|
)
|
|
1254
1664
|
if not authenticate_dict:
|
|
1255
1665
|
return None
|
|
1256
1666
|
return authenticate_dict
|
|
1257
1667
|
if response.status_code == 401 and retries == 0:
|
|
1258
|
-
logger.warning("Session has expired - try to re-authenticate...")
|
|
1668
|
+
self.logger.warning("Session has expired - try to re-authenticate...")
|
|
1259
1669
|
self.authenticate(revalidate=True)
|
|
1260
1670
|
retries += 1
|
|
1261
1671
|
else:
|
|
1262
|
-
logger.error(response.text)
|
|
1672
|
+
self.logger.error(response.text)
|
|
1263
1673
|
return None
|
|
1264
1674
|
|
|
1265
1675
|
# end method definition
|
|
1266
1676
|
|
|
1267
|
-
def validate_workspace_response(
|
|
1268
|
-
|
|
1269
|
-
response: str,
|
|
1270
|
-
workspace_name: str
|
|
1271
|
-
) -> bool:
|
|
1272
|
-
"""
|
|
1273
|
-
Verify if the workspace exists or was created successfully.
|
|
1677
|
+
def validate_workspace_response(self, response: str, workspace_name: str) -> bool:
|
|
1678
|
+
"""Verify if the workspace exists or was created successfully.
|
|
1274
1679
|
|
|
1275
1680
|
Args:
|
|
1276
1681
|
response (str): response to validate
|
|
@@ -1278,16 +1683,17 @@ class OTAWP:
|
|
|
1278
1683
|
|
|
1279
1684
|
Returns:
|
|
1280
1685
|
bool: True if the workspace exists or was created successfully, else False.
|
|
1686
|
+
|
|
1281
1687
|
"""
|
|
1282
1688
|
|
|
1283
1689
|
if "Object already exists" in response or "createWorkspaceResponse" in response:
|
|
1284
|
-
logger.info(
|
|
1690
|
+
self.logger.info(
|
|
1285
1691
|
"The workspace already exists or was created with the name -> '%s'",
|
|
1286
1692
|
workspace_name,
|
|
1287
1693
|
)
|
|
1288
1694
|
return True
|
|
1289
1695
|
|
|
1290
|
-
logger.info(
|
|
1696
|
+
self.logger.info(
|
|
1291
1697
|
"The workspace -> '%s' does not exist or was not created. Please verify configurtion!",
|
|
1292
1698
|
workspace_name,
|
|
1293
1699
|
)
|
|
@@ -1295,41 +1701,61 @@ class OTAWP:
|
|
|
1295
1701
|
|
|
1296
1702
|
# end method definition
|
|
1297
1703
|
|
|
1298
|
-
def is_workspace_already_exists(
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
workspace_name: str
|
|
1302
|
-
) -> bool:
|
|
1303
|
-
"""verify is workspace exists
|
|
1704
|
+
def is_workspace_already_exists(self, response: str, workspace_name: str) -> bool:
|
|
1705
|
+
"""Verify if workspace exists.
|
|
1706
|
+
|
|
1304
1707
|
Args:
|
|
1305
|
-
|
|
1708
|
+
response (str):
|
|
1709
|
+
The response.
|
|
1710
|
+
workspace_name (str):
|
|
1711
|
+
The name of the workspace.
|
|
1712
|
+
|
|
1306
1713
|
Returns:
|
|
1307
|
-
bool:
|
|
1714
|
+
bool:
|
|
1715
|
+
Return True if workspace exist else return false.
|
|
1716
|
+
|
|
1308
1717
|
"""
|
|
1309
1718
|
|
|
1310
1719
|
if "Object already exists" in response:
|
|
1311
|
-
logger.info(
|
|
1312
|
-
"The workspace already exists with the name -> '%s'",
|
|
1720
|
+
self.logger.info(
|
|
1721
|
+
"The workspace already exists with the name -> '%s'",
|
|
1722
|
+
workspace_name,
|
|
1313
1723
|
)
|
|
1314
1724
|
return True
|
|
1315
|
-
logger.info(
|
|
1316
|
-
"The Workspace has been created with the name -> '%s'",
|
|
1725
|
+
self.logger.info(
|
|
1726
|
+
"The Workspace has been created with the name -> '%s'",
|
|
1727
|
+
workspace_name,
|
|
1317
1728
|
)
|
|
1318
1729
|
return False
|
|
1319
1730
|
|
|
1320
1731
|
# end method definition
|
|
1321
1732
|
|
|
1322
|
-
def create_workspace_with_retry(
|
|
1323
|
-
|
|
1324
|
-
|
|
1733
|
+
def create_workspace_with_retry(
|
|
1734
|
+
self,
|
|
1735
|
+
workspace_name: str,
|
|
1736
|
+
workspace_gui_id: str,
|
|
1737
|
+
) -> dict | None:
|
|
1738
|
+
"""Call create_workspace and retries if the response contains specific error messages.
|
|
1739
|
+
|
|
1325
1740
|
Retries until the response does not contain the errors or a max retry limit is reached.
|
|
1741
|
+
|
|
1742
|
+
Args:
|
|
1743
|
+
workspace_name (str):
|
|
1744
|
+
The workspace name.
|
|
1745
|
+
workspace_gui_id (str):
|
|
1746
|
+
The workspace GUI ID.
|
|
1747
|
+
|
|
1748
|
+
Returns:
|
|
1749
|
+
dict | None:
|
|
1750
|
+
The response of the workspace creation or None in case an error occured.
|
|
1751
|
+
|
|
1326
1752
|
"""
|
|
1327
1753
|
|
|
1328
1754
|
max_retries = 20 # Define the maximum number of retries
|
|
1329
1755
|
retries = 0
|
|
1330
1756
|
error_messages = [
|
|
1331
1757
|
"Collaborative Workspace Service Container is not able to handle the SOAP request",
|
|
1332
|
-
"Service Group Lookup failure"
|
|
1758
|
+
"Service Group Lookup failure",
|
|
1333
1759
|
]
|
|
1334
1760
|
|
|
1335
1761
|
while retries < max_retries:
|
|
@@ -1337,15 +1763,19 @@ class OTAWP:
|
|
|
1337
1763
|
|
|
1338
1764
|
# Check if any error message is in the response
|
|
1339
1765
|
if any(error_message in response for error_message in error_messages):
|
|
1340
|
-
logger.info(
|
|
1766
|
+
self.logger.info(
|
|
1767
|
+
"Workspace service error, waiting 60 seconds to retry... (Retry %d of %d)",
|
|
1768
|
+
retries + 1,
|
|
1769
|
+
max_retries,
|
|
1770
|
+
)
|
|
1341
1771
|
time.sleep(60)
|
|
1342
1772
|
retries += 1
|
|
1343
1773
|
else:
|
|
1344
|
-
logger.info("Collaborative Workspace Service Container is ready")
|
|
1774
|
+
self.logger.info("Collaborative Workspace Service Container is ready")
|
|
1345
1775
|
return response
|
|
1346
1776
|
|
|
1347
1777
|
# After max retries, log and return the response or handle as needed
|
|
1348
|
-
logger.error(
|
|
1778
|
+
self.logger.error(
|
|
1349
1779
|
"Max retries reached for workspace -> '%s', unable to create successfully.",
|
|
1350
1780
|
workspace_name,
|
|
1351
1781
|
)
|
|
@@ -1354,367 +1784,474 @@ class OTAWP:
|
|
|
1354
1784
|
# end method definition
|
|
1355
1785
|
|
|
1356
1786
|
def loan_management_runtime(self) -> dict | None:
|
|
1357
|
-
"""
|
|
1787
|
+
"""Create all runtime objects for loan management application.
|
|
1788
|
+
|
|
1358
1789
|
Args:
|
|
1359
1790
|
None
|
|
1360
1791
|
Returns:
|
|
1361
1792
|
None
|
|
1793
|
+
|
|
1362
1794
|
"""
|
|
1363
1795
|
|
|
1364
|
-
logger.debug(" RUNTIME -->> Category instance creation started ........ ")
|
|
1796
|
+
self.logger.debug(" RUNTIME -->> Category instance creation started ........ ")
|
|
1365
1797
|
category_resp_dict = []
|
|
1366
1798
|
if not self.verify_category_exists("Short Term Loan"):
|
|
1367
|
-
self.create_category("LOAN","Short Term Loan","Short Term Loan",1)
|
|
1799
|
+
self.create_category("LOAN", "Short Term Loan", "Short Term Loan", 1)
|
|
1368
1800
|
if not self.verify_category_exists("Long Term Loan"):
|
|
1369
|
-
self.create_category("LOAN","Long Term Loan","Long Term Loan",1)
|
|
1801
|
+
self.create_category("LOAN", "Long Term Loan", "Long Term Loan", 1)
|
|
1370
1802
|
if not self.verify_category_exists("Flexi Loan"):
|
|
1371
|
-
self.create_category("LOAN","Flexi Loan","Flexi Loan",1)
|
|
1803
|
+
self.create_category("LOAN", "Flexi Loan", "Flexi Loan", 1)
|
|
1372
1804
|
category_resp_dict = self.get_category_lists()
|
|
1373
|
-
logger.debug(" RUNTIME -->> Category instance creation ended")
|
|
1805
|
+
self.logger.debug(" RUNTIME -->> Category instance creation ended")
|
|
1374
1806
|
|
|
1375
1807
|
############################# Sub category
|
|
1376
|
-
logger.debug(
|
|
1808
|
+
self.logger.debug(
|
|
1809
|
+
" RUNTIME -->> Sub Category instance creation started ........",
|
|
1810
|
+
)
|
|
1377
1811
|
stl = 0
|
|
1378
1812
|
ltl = 0
|
|
1379
1813
|
fl = 0
|
|
1380
|
-
if not self.verify_sub_category_exists("Business",0,category_resp_dict):
|
|
1381
|
-
response_dict =
|
|
1814
|
+
if not self.verify_sub_category_exists("Business", 0, category_resp_dict):
|
|
1815
|
+
response_dict = self.create_sub_categoy(
|
|
1816
|
+
"Business",
|
|
1817
|
+
"Business",
|
|
1818
|
+
1,
|
|
1819
|
+
category_resp_dict[0],
|
|
1820
|
+
)
|
|
1382
1821
|
stl = response_dict["Identity"]["Id"]
|
|
1383
|
-
logger.info("Sub category id stl: %s ", stl)
|
|
1822
|
+
self.logger.info("Sub category id stl: %s ", stl)
|
|
1384
1823
|
else:
|
|
1385
|
-
stl = self.return_sub_category_exists_id("Business",0,category_resp_dict)
|
|
1386
|
-
logger.info("Sub category id stl -> %s ", stl)
|
|
1824
|
+
stl = self.return_sub_category_exists_id("Business", 0, category_resp_dict)
|
|
1825
|
+
self.logger.info("Sub category id stl -> %s ", stl)
|
|
1387
1826
|
|
|
1388
|
-
if not self.verify_sub_category_exists("Business",1,category_resp_dict):
|
|
1389
|
-
response_dict=self.create_sub_categoy(
|
|
1827
|
+
if not self.verify_sub_category_exists("Business", 1, category_resp_dict):
|
|
1828
|
+
response_dict = self.create_sub_categoy(
|
|
1829
|
+
"Business",
|
|
1830
|
+
"Business",
|
|
1831
|
+
1,
|
|
1832
|
+
category_resp_dict[1],
|
|
1833
|
+
)
|
|
1390
1834
|
ltl = response_dict["Identity"]["Id"]
|
|
1391
|
-
logger.info("Sub category id ltl -> %s ", ltl)
|
|
1835
|
+
self.logger.info("Sub category id ltl -> %s ", ltl)
|
|
1392
1836
|
else:
|
|
1393
|
-
ltl = self.return_sub_category_exists_id("Business",1,category_resp_dict)
|
|
1394
|
-
logger.info("Sub category id ltl -> %s ", ltl)
|
|
1395
|
-
if not self.verify_sub_category_exists("Business",2,category_resp_dict):
|
|
1396
|
-
response_dict= self.create_sub_categoy(
|
|
1837
|
+
ltl = self.return_sub_category_exists_id(name="Business", index=1, category_resp_dict=category_resp_dict)
|
|
1838
|
+
self.logger.info("Sub category id ltl -> %s ", ltl)
|
|
1839
|
+
if not self.verify_sub_category_exists(name="Business", index=2, category_resp_dict=category_resp_dict):
|
|
1840
|
+
response_dict = self.create_sub_categoy(
|
|
1841
|
+
"Business",
|
|
1842
|
+
"Business",
|
|
1843
|
+
1,
|
|
1844
|
+
category_resp_dict[2],
|
|
1845
|
+
)
|
|
1397
1846
|
fl = response_dict["Identity"]["Id"]
|
|
1398
|
-
logger.info("Sub category id fl -> %s ", fl)
|
|
1847
|
+
self.logger.info("Sub category id fl -> %s ", fl)
|
|
1399
1848
|
else:
|
|
1400
|
-
fl = self.return_sub_category_exists_id("Business",2,category_resp_dict)
|
|
1401
|
-
logger.info("Sub category id fl -> %s ", fl)
|
|
1402
|
-
logger.debug(" RUNTIME -->> Sub Category instance creation ended")
|
|
1849
|
+
fl = self.return_sub_category_exists_id(name="Business", index=2, category_resp_dict=category_resp_dict)
|
|
1850
|
+
self.logger.info("Sub category id fl -> %s ", fl)
|
|
1851
|
+
self.logger.debug(" RUNTIME -->> Sub Category instance creation ended")
|
|
1403
1852
|
|
|
1404
1853
|
############################# Case Types
|
|
1405
|
-
logger.debug(" RUNTIME -->> Case Types instance creation started ........")
|
|
1854
|
+
self.logger.debug(" RUNTIME -->> Case Types instance creation started ........")
|
|
1406
1855
|
case_type_list = []
|
|
1407
1856
|
|
|
1408
1857
|
if not self.vverify_case_type_exists("Query"):
|
|
1409
|
-
self.create_case_type("Query","Query",1)
|
|
1858
|
+
self.create_case_type("Query", "Query", 1)
|
|
1410
1859
|
if not self.vverify_case_type_exists("Help"):
|
|
1411
|
-
self.create_case_type("Help","Help",1)
|
|
1860
|
+
self.create_case_type("Help", "Help", 1)
|
|
1412
1861
|
if not self.vverify_case_type_exists("Update Contact Details"):
|
|
1413
|
-
self.create_case_type("Update Contact Details","Update Contact Details",1)
|
|
1862
|
+
self.create_case_type("Update Contact Details", "Update Contact Details", 1)
|
|
1414
1863
|
if not self.vverify_case_type_exists("New Loan Request"):
|
|
1415
|
-
self.create_case_type("New Loan Request","New Loan Request",1)
|
|
1864
|
+
self.create_case_type("New Loan Request", "New Loan Request", 1)
|
|
1416
1865
|
if not self.vverify_case_type_exists("Loan Closure"):
|
|
1417
|
-
self.create_case_type("Loan Closure","Loan Closure",1)
|
|
1866
|
+
self.create_case_type("Loan Closure", "Loan Closure", 1)
|
|
1418
1867
|
case_type_list = self.get_case_type_lists()
|
|
1419
|
-
logger.debug(" RUNTIME -->> Case Types instance creation ended")
|
|
1868
|
+
self.logger.debug(" RUNTIME -->> Case Types instance creation ended")
|
|
1420
1869
|
|
|
1421
1870
|
############################# CUSTMOR
|
|
1422
|
-
logger.debug(" RUNTIME -->> Customer instance creation stated ........")
|
|
1871
|
+
self.logger.debug(" RUNTIME -->> Customer instance creation stated ........")
|
|
1423
1872
|
customer_list = []
|
|
1424
1873
|
if not self.verify_customer_exists("InaPlex Limited"):
|
|
1425
|
-
self.create_customer(
|
|
1874
|
+
self.create_customer(
|
|
1875
|
+
"InaPlex Limited",
|
|
1876
|
+
"InaPlex Limited",
|
|
1877
|
+
"InaPlex Limited",
|
|
1878
|
+
)
|
|
1426
1879
|
|
|
1427
1880
|
if not self.verify_customer_exists("Interwoven, Inc"):
|
|
1428
|
-
self.create_customer(
|
|
1881
|
+
self.create_customer(
|
|
1882
|
+
"Interwoven, Inc",
|
|
1883
|
+
"Interwoven, Inc",
|
|
1884
|
+
"Interwoven, Inc",
|
|
1885
|
+
)
|
|
1429
1886
|
|
|
1430
1887
|
if not self.verify_customer_exists("Jones Lang LaSalle"):
|
|
1431
|
-
self.create_customer(
|
|
1888
|
+
self.create_customer(
|
|
1889
|
+
"Jones Lang LaSalle",
|
|
1890
|
+
"Jones Lang LaSalle",
|
|
1891
|
+
"Jones Lang LaSalle",
|
|
1892
|
+
)
|
|
1432
1893
|
|
|
1433
1894
|
if not self.verify_customer_exists("Key Point Consulting"):
|
|
1434
|
-
self.create_customer(
|
|
1895
|
+
self.create_customer(
|
|
1896
|
+
"Key Point Consulting",
|
|
1897
|
+
"Key Point Consulting",
|
|
1898
|
+
"Key Point Consulting",
|
|
1899
|
+
)
|
|
1435
1900
|
|
|
1436
1901
|
customer_list = self.get_customer_lists()
|
|
1437
|
-
logger.debug(" RUNTIME -->> Customer instance creation ended")
|
|
1902
|
+
self.logger.debug(" RUNTIME -->> Customer instance creation ended")
|
|
1438
1903
|
|
|
1439
1904
|
######################################## PRIORITY
|
|
1440
|
-
logger.debug(" RUNTIME -->> priority instance creation started ........")
|
|
1905
|
+
self.logger.debug(" RUNTIME -->> priority instance creation started ........")
|
|
1441
1906
|
prioity_list = []
|
|
1442
1907
|
if not self.verify_priority_exists("High"):
|
|
1443
|
-
self.create_priority("High","High",1)
|
|
1908
|
+
self.create_priority("High", "High", 1)
|
|
1444
1909
|
if not self.verify_priority_exists("Medium"):
|
|
1445
|
-
self.create_priority("Medium","Medium",1)
|
|
1910
|
+
self.create_priority("Medium", "Medium", 1)
|
|
1446
1911
|
if not self.verify_priority_exists("Low"):
|
|
1447
|
-
self.create_priority("Low","Low",1)
|
|
1912
|
+
self.create_priority("Low", "Low", 1)
|
|
1448
1913
|
prioity_list = self.get_priority_lists()
|
|
1449
|
-
logger.debug(" RUNTIME -->> priority instance creation ended")
|
|
1914
|
+
self.logger.debug(" RUNTIME -->> priority instance creation ended")
|
|
1450
1915
|
|
|
1451
1916
|
############################# LOAN
|
|
1452
1917
|
loan_for_business = "Loan for Business1"
|
|
1453
1918
|
loan_for_corporate_business = "Loan for Corporate Business1"
|
|
1454
1919
|
loan_for_business_loan_request = "Loan for Business Loan Request1"
|
|
1455
1920
|
|
|
1456
|
-
logger.debug(" RUNTIME -->> loan instance creation started ........")
|
|
1921
|
+
self.logger.debug(" RUNTIME -->> loan instance creation started ........")
|
|
1457
1922
|
loan_resp_dict = self.get_all_loan()
|
|
1458
1923
|
names = [item["Properties"]["Subject"] for item in loan_resp_dict["_embedded"]["AllCasesList"]]
|
|
1459
1924
|
if loan_for_business in names:
|
|
1460
|
-
logger.info("Customer record Loan_for_business exists")
|
|
1925
|
+
self.logger.info("Customer record Loan_for_business exists")
|
|
1461
1926
|
else:
|
|
1462
|
-
logger.info("Creating customer Record with Loan_for_business ")
|
|
1927
|
+
self.logger.info("Creating customer Record with Loan_for_business ")
|
|
1463
1928
|
response_dict = self.create_loan(
|
|
1464
|
-
loan_for_business,
|
|
1465
|
-
loan_for_business,
|
|
1466
|
-
1,
|
|
1467
|
-
2,
|
|
1468
|
-
category_resp_dict[0],
|
|
1469
|
-
stl,
|
|
1470
|
-
prioity_list[0],
|
|
1471
|
-
case_type_list[0],
|
|
1472
|
-
customer_list[0],
|
|
1929
|
+
subject=loan_for_business,
|
|
1930
|
+
description=loan_for_business,
|
|
1931
|
+
loan_amount=1,
|
|
1932
|
+
loan_duration_in_months=2,
|
|
1933
|
+
category=category_resp_dict[0],
|
|
1934
|
+
subcategory=stl,
|
|
1935
|
+
priority=prioity_list[0],
|
|
1936
|
+
service=case_type_list[0],
|
|
1937
|
+
customer=customer_list[0],
|
|
1473
1938
|
)
|
|
1474
1939
|
|
|
1475
1940
|
if loan_for_corporate_business in names:
|
|
1476
|
-
logger.info("Customer record Loan_for_Corporate_Business exists")
|
|
1941
|
+
self.logger.info("Customer record Loan_for_Corporate_Business exists")
|
|
1477
1942
|
else:
|
|
1478
|
-
logger.info(
|
|
1943
|
+
self.logger.info(
|
|
1944
|
+
"Creating customer Record with Loan_for_Corporate_Business ",
|
|
1945
|
+
)
|
|
1479
1946
|
response_dict = self.create_loan(
|
|
1480
|
-
loan_for_corporate_business,
|
|
1481
|
-
loan_for_corporate_business,
|
|
1482
|
-
1,
|
|
1483
|
-
2,
|
|
1484
|
-
category_resp_dict[1],
|
|
1485
|
-
ltl,
|
|
1486
|
-
prioity_list[1],
|
|
1487
|
-
case_type_list[1],
|
|
1488
|
-
customer_list[1],
|
|
1947
|
+
subject=loan_for_corporate_business,
|
|
1948
|
+
description=loan_for_corporate_business,
|
|
1949
|
+
loan_amount=1,
|
|
1950
|
+
loan_duration_in_months=2,
|
|
1951
|
+
category=category_resp_dict[1],
|
|
1952
|
+
subcategory=ltl,
|
|
1953
|
+
priority=prioity_list[1],
|
|
1954
|
+
service=case_type_list[1],
|
|
1955
|
+
customer=customer_list[1],
|
|
1489
1956
|
)
|
|
1490
1957
|
|
|
1491
1958
|
if loan_for_business_loan_request in names:
|
|
1492
|
-
logger.info("Customer record Loan_for_business_Loan_Request exists")
|
|
1959
|
+
self.logger.info("Customer record Loan_for_business_Loan_Request exists")
|
|
1493
1960
|
else:
|
|
1494
|
-
logger.info(
|
|
1961
|
+
self.logger.info(
|
|
1962
|
+
"Creating customer Record with loan_for_business_loan_request",
|
|
1963
|
+
)
|
|
1495
1964
|
response_dict = self.create_loan(
|
|
1496
|
-
loan_for_business_loan_request,
|
|
1497
|
-
loan_for_business_loan_request,
|
|
1498
|
-
1,
|
|
1499
|
-
2,
|
|
1500
|
-
category_resp_dict[2],
|
|
1501
|
-
fl,
|
|
1502
|
-
prioity_list[2],
|
|
1503
|
-
case_type_list[2],
|
|
1504
|
-
customer_list[2],
|
|
1965
|
+
subject=loan_for_business_loan_request,
|
|
1966
|
+
description=loan_for_business_loan_request,
|
|
1967
|
+
loan_amount=1,
|
|
1968
|
+
loan_duration_in_months=2,
|
|
1969
|
+
category=category_resp_dict[2],
|
|
1970
|
+
subcategory=fl,
|
|
1971
|
+
priority=prioity_list[2],
|
|
1972
|
+
service=case_type_list[2],
|
|
1973
|
+
customer=customer_list[2],
|
|
1505
1974
|
)
|
|
1506
|
-
logger.debug(" RUNTIME -->> loan instance creation ended")
|
|
1975
|
+
self.logger.debug(" RUNTIME -->> loan instance creation ended")
|
|
1507
1976
|
|
|
1508
1977
|
# end method definition
|
|
1509
1978
|
|
|
1510
1979
|
def get_category_lists(self) -> list:
|
|
1511
|
-
"""
|
|
1980
|
+
"""Get All category entty instances id's.
|
|
1981
|
+
|
|
1512
1982
|
Args:
|
|
1513
1983
|
None
|
|
1514
1984
|
Returns:
|
|
1515
1985
|
list: list of category IDs
|
|
1986
|
+
|
|
1516
1987
|
"""
|
|
1517
1988
|
|
|
1518
1989
|
category_resp_dict = []
|
|
1519
1990
|
categoy_resp_dict = self.get_all_categories()
|
|
1520
1991
|
for item in categoy_resp_dict["_embedded"]["CategoryList"]:
|
|
1521
1992
|
first_item_href = item["_links"]["item"]["href"]
|
|
1522
|
-
integer_value = int(re.search(r
|
|
1523
|
-
logger.info("Category created with ID -> %d", integer_value)
|
|
1993
|
+
integer_value = int(re.search(r"\d+", first_item_href).group())
|
|
1994
|
+
self.logger.info("Category created with ID -> %d", integer_value)
|
|
1524
1995
|
category_resp_dict.append(integer_value)
|
|
1525
|
-
logger.info("All extracted category IDs -> %s", category_resp_dict)
|
|
1996
|
+
self.logger.info("All extracted category IDs -> %s", category_resp_dict)
|
|
1526
1997
|
|
|
1527
1998
|
return category_resp_dict
|
|
1528
1999
|
|
|
1529
2000
|
# end method definition
|
|
1530
2001
|
|
|
1531
2002
|
def get_case_type_lists(self) -> list:
|
|
1532
|
-
"""Get All CaseType entity instances IDs
|
|
2003
|
+
"""Get All CaseType entity instances IDs.
|
|
2004
|
+
|
|
1533
2005
|
Args:
|
|
1534
2006
|
None
|
|
2007
|
+
|
|
1535
2008
|
Returns:
|
|
1536
|
-
list:
|
|
2009
|
+
list:
|
|
2010
|
+
List of all case type IDs.
|
|
2011
|
+
|
|
1537
2012
|
"""
|
|
1538
2013
|
|
|
1539
2014
|
case_type_list = []
|
|
1540
2015
|
casetype_resp_dict = self.get_all_case_type()
|
|
1541
2016
|
for item in casetype_resp_dict["_embedded"]["AllCaseTypes"]:
|
|
1542
2017
|
first_item_href = item["_links"]["item"]["href"]
|
|
1543
|
-
integer_value = int(re.search(r
|
|
1544
|
-
logger.info("Case type created with ID -> %d", integer_value)
|
|
2018
|
+
integer_value = int(re.search(r"\d+", first_item_href).group())
|
|
2019
|
+
self.logger.info("Case type created with ID -> %d", integer_value)
|
|
1545
2020
|
case_type_list.append(integer_value)
|
|
1546
|
-
logger.info("All extracted case type IDs -> %s", case_type_list)
|
|
2021
|
+
self.logger.info("All extracted case type IDs -> %s", case_type_list)
|
|
1547
2022
|
|
|
1548
2023
|
return case_type_list
|
|
1549
2024
|
|
|
1550
2025
|
# end method definition
|
|
1551
2026
|
|
|
1552
2027
|
def get_customer_lists(self) -> list:
|
|
1553
|
-
"""Get all customer entity instances id's
|
|
2028
|
+
"""Get all customer entity instances id's.
|
|
2029
|
+
|
|
1554
2030
|
Args:
|
|
1555
2031
|
None
|
|
1556
2032
|
Returns:
|
|
1557
|
-
list:
|
|
2033
|
+
list:
|
|
2034
|
+
A list of all customer IDs.
|
|
2035
|
+
|
|
1558
2036
|
"""
|
|
1559
2037
|
|
|
1560
2038
|
customer_list = []
|
|
1561
2039
|
customer_resp_dict = self.get_all_customers()
|
|
1562
2040
|
for item in customer_resp_dict["_embedded"]["CustomerList"]:
|
|
1563
2041
|
first_item_href = item["_links"]["item"]["href"]
|
|
1564
|
-
integer_value = int(re.search(r
|
|
1565
|
-
logger.info("Customer created with ID -> %d", integer_value)
|
|
2042
|
+
integer_value = int(re.search(r"\d+", first_item_href).group())
|
|
2043
|
+
self.logger.info("Customer created with ID -> %d", integer_value)
|
|
1566
2044
|
customer_list.append(integer_value)
|
|
1567
|
-
logger.info("All extracted Customer IDs -> %s ", customer_list)
|
|
2045
|
+
self.logger.info("All extracted Customer IDs -> %s ", customer_list)
|
|
2046
|
+
|
|
1568
2047
|
return customer_list
|
|
1569
2048
|
|
|
1570
2049
|
# end method definition
|
|
1571
2050
|
|
|
1572
2051
|
def get_priority_lists(self) -> list:
|
|
1573
|
-
"""
|
|
2052
|
+
"""Get all priority entity instances IDs.
|
|
2053
|
+
|
|
1574
2054
|
Args:
|
|
1575
2055
|
None
|
|
1576
2056
|
Returns:
|
|
1577
|
-
list:
|
|
2057
|
+
list:
|
|
2058
|
+
A list with all priority IDs.
|
|
2059
|
+
|
|
1578
2060
|
"""
|
|
1579
2061
|
|
|
1580
2062
|
prioity_list = []
|
|
1581
2063
|
authenticate_dict = self.get_all_priorities()
|
|
1582
2064
|
for item in authenticate_dict["_embedded"]["PriorityList"]:
|
|
1583
2065
|
first_item_href = item["_links"]["item"]["href"]
|
|
1584
|
-
integer_value = int(re.search(r
|
|
1585
|
-
logger.info("Priority created with ID -> %d", integer_value)
|
|
2066
|
+
integer_value = int(re.search(r"\d+", first_item_href).group())
|
|
2067
|
+
self.logger.info("Priority created with ID -> %d", integer_value)
|
|
1586
2068
|
prioity_list.append(integer_value)
|
|
1587
|
-
logger.info("All extracted priority IDs -> %s ", prioity_list)
|
|
2069
|
+
self.logger.info("All extracted priority IDs -> %s ", prioity_list)
|
|
1588
2070
|
|
|
1589
2071
|
return prioity_list
|
|
1590
2072
|
|
|
1591
2073
|
# end method definition
|
|
1592
2074
|
|
|
1593
2075
|
def verify_category_exists(self, name: str) -> bool:
|
|
1594
|
-
"""
|
|
2076
|
+
"""Verify category entity instance already exists.
|
|
2077
|
+
|
|
1595
2078
|
Args:
|
|
1596
|
-
name (str):
|
|
2079
|
+
name (str):
|
|
2080
|
+
The name of the category.
|
|
2081
|
+
|
|
1597
2082
|
Returns:
|
|
1598
|
-
bool:
|
|
2083
|
+
bool:
|
|
2084
|
+
Returns True if already record exists with same name, else returns False.
|
|
2085
|
+
|
|
1599
2086
|
"""
|
|
1600
2087
|
|
|
1601
2088
|
categoy_resp_dict = self.get_all_categories()
|
|
1602
2089
|
names = [item["Properties"]["Name"] for item in categoy_resp_dict["_embedded"]["CategoryList"]]
|
|
1603
2090
|
if name in names:
|
|
1604
|
-
logger.info("Category record -> '%s' already exists", name)
|
|
2091
|
+
self.logger.info("Category record -> '%s' already exists", name)
|
|
1605
2092
|
return True
|
|
1606
|
-
logger.info("Creating category record -> '%s'", name)
|
|
2093
|
+
self.logger.info("Creating category record -> '%s'", name)
|
|
1607
2094
|
|
|
1608
2095
|
return False
|
|
1609
2096
|
|
|
1610
2097
|
# end method definition
|
|
1611
2098
|
|
|
1612
2099
|
def vverify_case_type_exists(self, name: str) -> bool:
|
|
1613
|
-
"""
|
|
2100
|
+
"""Verify case type entity instance already exists.
|
|
2101
|
+
|
|
1614
2102
|
Args:
|
|
1615
|
-
name (str):
|
|
2103
|
+
name (str):
|
|
2104
|
+
The name of the case type.
|
|
2105
|
+
|
|
1616
2106
|
Returns:
|
|
1617
|
-
bool:
|
|
2107
|
+
bool:
|
|
2108
|
+
Returns True if already record exists with same name, else returns False.
|
|
2109
|
+
|
|
1618
2110
|
"""
|
|
1619
2111
|
|
|
1620
2112
|
casetype_resp_dict = self.get_all_case_type()
|
|
1621
2113
|
names = [item["Properties"]["Name"] for item in casetype_resp_dict["_embedded"]["AllCaseTypes"]]
|
|
1622
2114
|
if name in names:
|
|
1623
|
-
logger.info("Case type record -> '%s' already exists", name)
|
|
2115
|
+
self.logger.info("Case type record -> '%s' already exists", name)
|
|
1624
2116
|
return True
|
|
1625
|
-
logger.info("Creating case type record -> '%s'", name)
|
|
2117
|
+
self.logger.info("Creating case type record -> '%s'", name)
|
|
1626
2118
|
|
|
1627
2119
|
return False
|
|
1628
2120
|
|
|
1629
2121
|
# end method definition
|
|
1630
2122
|
|
|
1631
2123
|
def verify_customer_exists(self, name: str) -> bool:
|
|
1632
|
-
"""
|
|
2124
|
+
"""Verify cusomer entty instance already exists.
|
|
2125
|
+
|
|
1633
2126
|
Args:
|
|
1634
|
-
name (str):
|
|
2127
|
+
name (str):
|
|
2128
|
+
The name of the customer.
|
|
2129
|
+
|
|
1635
2130
|
Returns:
|
|
1636
|
-
bool:
|
|
2131
|
+
bool:
|
|
2132
|
+
Returns True if already record exists with same name, else returns False
|
|
2133
|
+
|
|
1637
2134
|
"""
|
|
2135
|
+
|
|
1638
2136
|
customer_resp_dict = self.get_all_customers()
|
|
1639
2137
|
names = [item["Properties"]["CustomerName"] for item in customer_resp_dict["_embedded"]["CustomerList"]]
|
|
1640
2138
|
if name in names:
|
|
1641
|
-
logger.info("Customer -> '%s' already exists", name)
|
|
2139
|
+
self.logger.info("Customer -> '%s' already exists", name)
|
|
1642
2140
|
return True
|
|
1643
|
-
logger.info("Creating customer -> '%s'", name)
|
|
2141
|
+
self.logger.info("Creating customer -> '%s'", name)
|
|
1644
2142
|
return False
|
|
1645
2143
|
|
|
1646
2144
|
# end method definition
|
|
1647
2145
|
|
|
1648
2146
|
def verify_priority_exists(self, name: str) -> bool:
|
|
1649
|
-
"""
|
|
2147
|
+
"""Verify priority entity instance already exists.
|
|
2148
|
+
|
|
1650
2149
|
Args:
|
|
1651
|
-
name (str):
|
|
2150
|
+
name (str):
|
|
2151
|
+
The name of the priority.
|
|
2152
|
+
|
|
1652
2153
|
Returns:
|
|
1653
|
-
bool:
|
|
2154
|
+
bool:
|
|
2155
|
+
Returns True if already record exists with same name, else returns False
|
|
2156
|
+
|
|
1654
2157
|
"""
|
|
1655
2158
|
|
|
1656
2159
|
authenticate_dict = self.get_all_priorities()
|
|
1657
2160
|
names = [item["Properties"]["Name"] for item in authenticate_dict["_embedded"]["PriorityList"]]
|
|
1658
2161
|
if name in names:
|
|
1659
|
-
logger.info("Priority -> '%s' already exists", name)
|
|
2162
|
+
self.logger.info("Priority -> '%s' already exists", name)
|
|
1660
2163
|
return True
|
|
1661
|
-
logger.info("Creating priority -> '%s'", name)
|
|
2164
|
+
self.logger.info("Creating priority -> '%s'", name)
|
|
1662
2165
|
|
|
1663
2166
|
return False
|
|
1664
2167
|
|
|
1665
2168
|
# end method definition
|
|
1666
2169
|
|
|
1667
|
-
def verify_sub_category_exists(
|
|
1668
|
-
|
|
2170
|
+
def verify_sub_category_exists(
|
|
2171
|
+
self,
|
|
2172
|
+
name: str,
|
|
2173
|
+
index: int,
|
|
2174
|
+
category_resp_dict: list,
|
|
2175
|
+
) -> bool:
|
|
2176
|
+
"""Verify sub category entity instance already exists.
|
|
2177
|
+
|
|
1669
2178
|
Args:
|
|
1670
|
-
name (str):
|
|
2179
|
+
name (str):
|
|
2180
|
+
The name of the sub category.
|
|
2181
|
+
index (int):
|
|
2182
|
+
The index of the sub category.
|
|
2183
|
+
category_resp_dict (list):
|
|
2184
|
+
TODO: add description
|
|
2185
|
+
|
|
1671
2186
|
Returns:
|
|
1672
|
-
bool:
|
|
2187
|
+
bool:
|
|
2188
|
+
Returns true if record already exists with same name, else returns false.
|
|
2189
|
+
|
|
1673
2190
|
"""
|
|
1674
2191
|
|
|
1675
2192
|
subcategoy_resp_dict = self.get_all_sub_categeries(category_resp_dict[index])
|
|
1676
2193
|
names = [item["Properties"]["Name"] for item in subcategoy_resp_dict["_embedded"]["SubCategory"]]
|
|
1677
|
-
stl=0
|
|
2194
|
+
stl = 0
|
|
1678
2195
|
if name in names:
|
|
1679
|
-
logger.info("Sub category -> '%s' already exists", name)
|
|
2196
|
+
self.logger.info("Sub category -> '%s' already exists", name)
|
|
1680
2197
|
for item in subcategoy_resp_dict["_embedded"]["SubCategory"]:
|
|
1681
2198
|
stl = item["Identity"]["Id"]
|
|
1682
|
-
logger.info("Sub category created with ID -> %s", stl)
|
|
2199
|
+
self.logger.info("Sub category created with ID -> %s", stl)
|
|
1683
2200
|
return True
|
|
1684
|
-
logger.info("Creating sub category -> '%s'", name)
|
|
2201
|
+
self.logger.info("Creating sub category -> '%s'", name)
|
|
1685
2202
|
|
|
1686
2203
|
return False
|
|
1687
2204
|
|
|
1688
2205
|
# end method definition
|
|
1689
2206
|
|
|
1690
|
-
def return_sub_category_exists_id(
|
|
1691
|
-
|
|
2207
|
+
def return_sub_category_exists_id(
|
|
2208
|
+
self,
|
|
2209
|
+
name: str,
|
|
2210
|
+
index: int,
|
|
2211
|
+
category_resp_dict: list,
|
|
2212
|
+
) -> int:
|
|
2213
|
+
"""Verify sub category entity instance id already exists.
|
|
2214
|
+
|
|
1692
2215
|
Args:
|
|
1693
|
-
name (str):
|
|
2216
|
+
name (str):
|
|
2217
|
+
The name of the sub-category.
|
|
2218
|
+
index (int):
|
|
2219
|
+
TODO: add description
|
|
2220
|
+
category_resp_dict (list):
|
|
2221
|
+
TODO: add description!
|
|
2222
|
+
|
|
1694
2223
|
Returns:
|
|
1695
|
-
bool:
|
|
2224
|
+
bool:
|
|
2225
|
+
Returns true if record already exists with same name, else returns false.
|
|
2226
|
+
|
|
1696
2227
|
"""
|
|
1697
2228
|
|
|
1698
2229
|
subcategoy_resp_dict = self.get_all_sub_categeries(category_resp_dict[index])
|
|
1699
2230
|
names = [item["Properties"]["Name"] for item in subcategoy_resp_dict["_embedded"]["SubCategory"]]
|
|
1700
|
-
stl=0
|
|
1701
|
-
if
|
|
1702
|
-
logger.info("Sub category record -> '%s' already exists", name)
|
|
2231
|
+
stl = 0
|
|
2232
|
+
if name in names:
|
|
2233
|
+
self.logger.info("Sub category record -> '%s' already exists", name)
|
|
1703
2234
|
for item in subcategoy_resp_dict["_embedded"]["SubCategory"]:
|
|
1704
2235
|
stl = item["Identity"]["Id"]
|
|
1705
|
-
logger.info("Sub category created with ID -> %s", stl)
|
|
2236
|
+
self.logger.info("Sub category created with ID -> %s", stl)
|
|
1706
2237
|
return stl
|
|
1707
2238
|
|
|
1708
2239
|
return None
|
|
1709
2240
|
|
|
1710
2241
|
# end method definition
|
|
1711
2242
|
|
|
1712
|
-
def create_users_from_config_file(self, otawpsection: str, _otds: OTDS):
|
|
1713
|
-
"""
|
|
2243
|
+
def create_users_from_config_file(self, otawpsection: str, _otds: OTDS) -> None:
|
|
2244
|
+
"""Read user information from customizer file and call create user method.
|
|
2245
|
+
|
|
1714
2246
|
Args:
|
|
1715
|
-
otawpsection (str):
|
|
2247
|
+
otawpsection (str):
|
|
2248
|
+
YAML block related to appworks
|
|
2249
|
+
_otds:
|
|
2250
|
+
The OTDS object.
|
|
2251
|
+
|
|
1716
2252
|
Returns:
|
|
1717
2253
|
None
|
|
2254
|
+
|
|
1718
2255
|
"""
|
|
1719
2256
|
|
|
1720
2257
|
otds = otawpsection.get("otds", {})
|
|
@@ -1735,29 +2272,35 @@ class OTAWP:
|
|
|
1735
2272
|
for role in roles:
|
|
1736
2273
|
_otds.add_user_to_group(
|
|
1737
2274
|
user.get("name") + "@" + user.get("partition"),
|
|
1738
|
-
# user.get('name'),
|
|
1739
2275
|
role.get("name"),
|
|
1740
2276
|
)
|
|
1741
2277
|
else:
|
|
1742
|
-
logger.error(
|
|
1743
|
-
"Verifying Users section: roles section not presented in yaml for otds users"
|
|
2278
|
+
self.logger.error(
|
|
2279
|
+
"Verifying Users section: roles section not presented in yaml for otds users",
|
|
1744
2280
|
)
|
|
1745
2281
|
else:
|
|
1746
|
-
logger.error(
|
|
1747
|
-
"Verifying Users section: user section not presented in yaml"
|
|
2282
|
+
self.logger.error(
|
|
2283
|
+
"Verifying Users section: user section not presented in yaml",
|
|
1748
2284
|
)
|
|
1749
2285
|
else:
|
|
1750
|
-
logger.error(
|
|
2286
|
+
self.logger.error(
|
|
2287
|
+
"Verifying Users section: otds section not presented in yaml",
|
|
2288
|
+
)
|
|
1751
2289
|
|
|
1752
2290
|
# end method definition
|
|
1753
2291
|
|
|
1754
|
-
def create_roles_from_config_file(self, otawpsection: str, _otds: OTDS):
|
|
1755
|
-
"""
|
|
2292
|
+
def create_roles_from_config_file(self, otawpsection: str, _otds: OTDS) -> None:
|
|
2293
|
+
"""Read grop information from customizer file and call create grop method.
|
|
2294
|
+
|
|
1756
2295
|
Args:
|
|
1757
|
-
otawpsection (str):
|
|
1758
|
-
|
|
2296
|
+
otawpsection (str):
|
|
2297
|
+
YAML block related to appworks.
|
|
2298
|
+
_otds (object):
|
|
2299
|
+
The OTDS object used to access the OTDS REST API.
|
|
2300
|
+
|
|
1759
2301
|
Returns:
|
|
1760
2302
|
None
|
|
2303
|
+
|
|
1761
2304
|
"""
|
|
1762
2305
|
|
|
1763
2306
|
otds = otawpsection.get("otds", {})
|
|
@@ -1773,20 +2316,26 @@ class OTAWP:
|
|
|
1773
2316
|
role.get("description"),
|
|
1774
2317
|
)
|
|
1775
2318
|
else:
|
|
1776
|
-
logger.error(
|
|
1777
|
-
"Verifying roles section: roles section not presented in yaml"
|
|
2319
|
+
self.logger.error(
|
|
2320
|
+
"Verifying roles section: roles section not presented in yaml",
|
|
1778
2321
|
)
|
|
1779
2322
|
else:
|
|
1780
|
-
logger.error(
|
|
2323
|
+
self.logger.error(
|
|
2324
|
+
"Verifying roles section: otds section not presented in yaml",
|
|
2325
|
+
)
|
|
1781
2326
|
|
|
1782
2327
|
# end method definition
|
|
1783
2328
|
|
|
1784
|
-
def create_loanruntime_from_config_file(self, platform: str):
|
|
1785
|
-
"""
|
|
2329
|
+
def create_loanruntime_from_config_file(self, platform: str) -> None:
|
|
2330
|
+
"""Verify flag and call loan_management_runtime().
|
|
2331
|
+
|
|
1786
2332
|
Args:
|
|
1787
|
-
platform (str):
|
|
2333
|
+
platform (str):
|
|
2334
|
+
YAML block related to platform.
|
|
2335
|
+
|
|
1788
2336
|
Returns:
|
|
1789
2337
|
None
|
|
2338
|
+
|
|
1790
2339
|
"""
|
|
1791
2340
|
|
|
1792
2341
|
runtime = platform.get("runtime", {})
|
|
@@ -1797,14 +2346,344 @@ class OTAWP:
|
|
|
1797
2346
|
if app_name == "loanManagement":
|
|
1798
2347
|
self.loan_management_runtime()
|
|
1799
2348
|
else:
|
|
1800
|
-
logger.error(
|
|
1801
|
-
"Verifying runtime section: loanManagement not exits in yaml entry"
|
|
2349
|
+
self.logger.error(
|
|
2350
|
+
"Verifying runtime section: loanManagement not exits in yaml entry",
|
|
1802
2351
|
)
|
|
1803
2352
|
else:
|
|
1804
|
-
logger.error(
|
|
1805
|
-
"Verifying runtime section: App name section is empty in yaml"
|
|
2353
|
+
self.logger.error(
|
|
2354
|
+
"Verifying runtime section: App name section is empty in yaml",
|
|
1806
2355
|
)
|
|
1807
2356
|
else:
|
|
1808
|
-
logger.error(
|
|
2357
|
+
self.logger.error(
|
|
2358
|
+
"Verifying runtime section: Runtime section is empty in yaml",
|
|
2359
|
+
)
|
|
2360
|
+
|
|
2361
|
+
# end method definition
|
|
2362
|
+
def create_cws_config(
|
|
2363
|
+
self,
|
|
2364
|
+
partition: str,
|
|
2365
|
+
resource_name: str,
|
|
2366
|
+
otcs_url: str,
|
|
2367
|
+
) -> dict | None:
|
|
2368
|
+
"""Create a workspace configuration in CWS.
|
|
2369
|
+
|
|
2370
|
+
Args:
|
|
2371
|
+
partition (str): The partition name for the workspace.
|
|
2372
|
+
resource_name (str): The resource name.
|
|
2373
|
+
otcs_url (str): The OTCS endpoint URL.
|
|
2374
|
+
|
|
2375
|
+
Returns:
|
|
2376
|
+
dict | None: Response dictionary if successful, or None if the request fails.
|
|
2377
|
+
|
|
2378
|
+
"""
|
|
2379
|
+
self.logger.info("Creating CWS config for partition '%s' and resource '%s'...", partition, resource_name)
|
|
2380
|
+
|
|
2381
|
+
# Construct the SOAP request body
|
|
2382
|
+
cws_config_req_xml = f"""
|
|
2383
|
+
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
|
|
2384
|
+
<SOAP:Header>
|
|
2385
|
+
<header xmlns="http://schemas.cordys.com/General/1.0/">
|
|
2386
|
+
<Logger/>
|
|
2387
|
+
</header>
|
|
2388
|
+
<i18n:international xmlns:i18n="http://www.w3.org/2005/09/ws-i18n">
|
|
2389
|
+
<i18n:locale>en-US</i18n:locale>
|
|
2390
|
+
</i18n:international>
|
|
2391
|
+
</SOAP:Header>
|
|
2392
|
+
<SOAP:Body>
|
|
2393
|
+
<UpdateXMLObject xmlns="http://schemas.cordys.com/1.0/xmlstore">
|
|
2394
|
+
<tuple lastModified="{int(time.time() * 1000)}"
|
|
2395
|
+
key="/com/ot-ps/csws/otcs_ws_config.xml"
|
|
2396
|
+
level="organization"
|
|
2397
|
+
name="otcs_ws_config.xml"
|
|
2398
|
+
original="/com/ot-ps/csws/otcs_ws_config.xml"
|
|
2399
|
+
version="organization">
|
|
2400
|
+
<new>
|
|
2401
|
+
<CSWSConfig>
|
|
2402
|
+
<Partition>{partition}</Partition>
|
|
2403
|
+
<EndPointUrl>{otcs_url}/cws/services/Authentication</EndPointUrl>
|
|
2404
|
+
<Resources>
|
|
2405
|
+
<Resource type="Cordys">
|
|
2406
|
+
<Name>__OTDS#Shared#Platform#Resource__</Name>
|
|
2407
|
+
<Space>shared</Space>
|
|
2408
|
+
</Resource>
|
|
2409
|
+
<Resource type="OTCS">
|
|
2410
|
+
<Name>{resource_name}</Name>
|
|
2411
|
+
<Space>shared</Space>
|
|
2412
|
+
</Resource>
|
|
2413
|
+
</Resources>
|
|
2414
|
+
</CSWSConfig>
|
|
2415
|
+
</new>
|
|
2416
|
+
</tuple>
|
|
2417
|
+
</UpdateXMLObject>
|
|
2418
|
+
</SOAP:Body>
|
|
2419
|
+
</SOAP:Envelope>
|
|
2420
|
+
"""
|
|
2421
|
+
|
|
2422
|
+
retries = 0
|
|
2423
|
+
max_retries = 20 # Maximum retry limit
|
|
2424
|
+
error_messages = [
|
|
2425
|
+
"Collaborative Workspace Service Container is not able to handle the SOAP request",
|
|
2426
|
+
"Service Group Lookup failure",
|
|
2427
|
+
]
|
|
2428
|
+
|
|
2429
|
+
while retries < max_retries:
|
|
2430
|
+
try:
|
|
2431
|
+
response = requests.post(
|
|
2432
|
+
url=self.gateway_url(),
|
|
2433
|
+
data=cws_config_req_xml,
|
|
2434
|
+
headers=REQUEST_HEADERS,
|
|
2435
|
+
cookies=self.cookie(),
|
|
2436
|
+
timeout=None,
|
|
2437
|
+
)
|
|
2438
|
+
|
|
2439
|
+
# Handle successful response
|
|
2440
|
+
if response.ok:
|
|
2441
|
+
if any(error_message in response.text for error_message in error_messages):
|
|
2442
|
+
self.logger.warning(
|
|
2443
|
+
"Service error detected, retrying in 60 seconds... (Retry %d of %d)",
|
|
2444
|
+
retries + 1,
|
|
2445
|
+
max_retries,
|
|
2446
|
+
)
|
|
2447
|
+
time.sleep(60)
|
|
2448
|
+
retries += 1
|
|
2449
|
+
else:
|
|
2450
|
+
self.logger.info("CWS config created successfully.")
|
|
2451
|
+
return response.text
|
|
2452
|
+
|
|
2453
|
+
# Handle session expiration
|
|
2454
|
+
if response.status_code == 401 and retries == 0:
|
|
2455
|
+
self.logger.warning("Session expired. Re-authenticating...")
|
|
2456
|
+
self.authenticate(revalidate=True)
|
|
2457
|
+
retries += 1
|
|
2458
|
+
continue
|
|
2459
|
+
|
|
2460
|
+
# Handle case where object has been changed by another user
|
|
2461
|
+
if "Object has been changed by other user" in response.text:
|
|
2462
|
+
self.logger.info("CWS config already exists")
|
|
2463
|
+
return response.text
|
|
2464
|
+
|
|
2465
|
+
# Log errors for failed requests
|
|
2466
|
+
self.logger.error("Failed to create CWS config: %s", response.text)
|
|
2467
|
+
time.sleep(60)
|
|
2468
|
+
retries += 1
|
|
2469
|
+
|
|
2470
|
+
except requests.RequestException:
|
|
2471
|
+
self.logger.error("Request failed during CWS config creation")
|
|
2472
|
+
retries += 1
|
|
2473
|
+
|
|
2474
|
+
# Log when retries are exhausted
|
|
2475
|
+
self.logger.error("Retry limit exceeded. CWS config creation failed.")
|
|
2476
|
+
return None
|
|
2477
|
+
|
|
2478
|
+
# end method definition
|
|
2479
|
+
def verify_user_having_role(self, organization: str, user_name: str, role_name: str) -> bool:
|
|
2480
|
+
"""Verify if the user has the specified role.
|
|
2481
|
+
|
|
2482
|
+
Args:
|
|
2483
|
+
organization(str): organization name
|
|
2484
|
+
user_name (str): The username to verify.
|
|
2485
|
+
role_name (str): The role to check for the user.
|
|
2486
|
+
|
|
2487
|
+
Returns:
|
|
2488
|
+
bool: True if the user has the role, False if not, or None if request fails.
|
|
2489
|
+
|
|
2490
|
+
"""
|
|
2491
|
+
self.logger.info("Verifying user '%s' has role '%s' started.", user_name, role_name)
|
|
2492
|
+
|
|
2493
|
+
# Construct the SOAP request body
|
|
2494
|
+
cws_config_req_xml = f"""
|
|
2495
|
+
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
|
|
2496
|
+
<SOAP:Header xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
|
|
2497
|
+
<header xmlns="http://schemas.cordys.com/General/1.0/">
|
|
2498
|
+
<Logger xmlns="http://schemas.cordys.com/General/1.0/"/>
|
|
2499
|
+
</header>
|
|
2500
|
+
<i18n:international xmlns:i18n="http://www.w3.org/2005/09/ws-i18n">
|
|
2501
|
+
<i18n:locale>en-US</i18n:locale>
|
|
2502
|
+
</i18n:international>
|
|
2503
|
+
</SOAP:Header>
|
|
2504
|
+
<SOAP:Body>
|
|
2505
|
+
<SearchLDAP xmlns:xfr="http://schemas.cordys.com/1.0/xforms/runtime" xmlns="http://schemas.cordys.com/1.0/ldap">
|
|
2506
|
+
<dn xmlns="http://schemas.cordys.com/1.0/ldap">cn=organizational users,o={organization},cn=cordys,cn=defaultInst,o=opentext.net</dn>
|
|
2507
|
+
<scope xmlns="http://schemas.cordys.com/1.0/ldap">1</scope>
|
|
2508
|
+
<filter xmlns="http://schemas.cordys.com/1.0/ldap">&(objectclass=busorganizationaluser)(&(!(cn=SYSTEM))(!(cn=anonymous))(!(cn=wcpLicUser)))(|(description=*{user_name}*)(&(!(description=*))(cn=*{user_name}*)))</filter>
|
|
2509
|
+
<sort xmlns="http://schemas.cordys.com/1.0/ldap">ascending</sort>
|
|
2510
|
+
<sortBy xmlns="http://schemas.cordys.com/1.0/ldap"/>
|
|
2511
|
+
<returnValues xmlns="http://schemas.cordys.com/1.0/ldap">false</returnValues>
|
|
2512
|
+
<return xmlns="http://schemas.cordys.com/1.0/ldap"/>
|
|
2513
|
+
</SearchLDAP>
|
|
2514
|
+
</SOAP:Body>
|
|
2515
|
+
</SOAP:Envelope>
|
|
2516
|
+
"""
|
|
2517
|
+
|
|
2518
|
+
retries = 0
|
|
2519
|
+
max_retries = 6 # Maximum retry limit
|
|
2520
|
+
while retries < max_retries:
|
|
2521
|
+
try:
|
|
2522
|
+
response = requests.post(
|
|
2523
|
+
url=self.gateway_url(),
|
|
2524
|
+
data=cws_config_req_xml,
|
|
2525
|
+
headers=REQUEST_HEADERS,
|
|
2526
|
+
cookies=self.cookie(),
|
|
2527
|
+
timeout=None,
|
|
2528
|
+
)
|
|
2529
|
+
|
|
2530
|
+
# Handle successful response
|
|
2531
|
+
if response.ok:
|
|
2532
|
+
if (
|
|
2533
|
+
role_name in response.text
|
|
2534
|
+
): # Corrected syntax for checking if 'Developer' is in the response text
|
|
2535
|
+
self.logger.info("Verifyied user '%s' already has the role '%s'.", user_name, role_name)
|
|
2536
|
+
return True # Assuming the user has the role if the response contains 'Developer'
|
|
2537
|
+
else:
|
|
2538
|
+
self.logger.info("Verifyied User '%s' not having role '%s'.", user_name, role_name)
|
|
2539
|
+
return False
|
|
2540
|
+
# Handle session expiration
|
|
2541
|
+
if response.status_code == 401 and retries == 0:
|
|
2542
|
+
self.logger.warning("Session expired. Re-authenticating...")
|
|
2543
|
+
self.authenticate(revalidate=True)
|
|
2544
|
+
retries += 1
|
|
2545
|
+
continue
|
|
2546
|
+
|
|
2547
|
+
# Log errors for failed requests
|
|
2548
|
+
self.logger.error("Failed to verify user role: %s", response.text)
|
|
2549
|
+
time.sleep(60)
|
|
2550
|
+
retries += 1
|
|
2551
|
+
|
|
2552
|
+
except requests.RequestException:
|
|
2553
|
+
self.logger.error("Request failed during user role verification")
|
|
2554
|
+
retries += 1
|
|
2555
|
+
|
|
2556
|
+
# Log when retries are exhausted
|
|
2557
|
+
self.logger.error("Retry limit exceeded. User role verification failed.")
|
|
2558
|
+
return False # Return False if the retries limit is exceeded
|
|
1809
2559
|
|
|
1810
2560
|
# end method definition
|
|
2561
|
+
|
|
2562
|
+
def assign_developer_role_to_user(self, organization: str, user_name: str, role_name: str) -> bool:
|
|
2563
|
+
"""Assign the 'Developer' role to the user and verify the role assignment.
|
|
2564
|
+
|
|
2565
|
+
Args:
|
|
2566
|
+
organization (str): The organization name.
|
|
2567
|
+
user_name (str): The username to verify.
|
|
2568
|
+
role_name (str): The role to be assigned.
|
|
2569
|
+
|
|
2570
|
+
Returns:
|
|
2571
|
+
bool: True if the user has the 'Developer' role, False otherwise.
|
|
2572
|
+
|
|
2573
|
+
"""
|
|
2574
|
+
self.logger.info("Assigning 'Developer' role to user '%s' in organization '%s'...", user_name, organization)
|
|
2575
|
+
|
|
2576
|
+
# Check if user already has the role before making the request
|
|
2577
|
+
if self.verify_user_having_role(organization, user_name, role_name):
|
|
2578
|
+
return True
|
|
2579
|
+
|
|
2580
|
+
# Construct the SOAP request body
|
|
2581
|
+
cws_config_req_xml = f"""\
|
|
2582
|
+
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
|
|
2583
|
+
<SOAP:Header xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
|
|
2584
|
+
<header xmlns="http://schemas.cordys.com/General/1.0/">
|
|
2585
|
+
<Logger xmlns="http://schemas.cordys.com/General/1.0/"/>
|
|
2586
|
+
</header>
|
|
2587
|
+
<i18n:international xmlns:i18n="http://www.w3.org/2005/09/ws-i18n">
|
|
2588
|
+
<i18n:locale>en-US</i18n:locale>
|
|
2589
|
+
</i18n:international>
|
|
2590
|
+
</SOAP:Header>
|
|
2591
|
+
<SOAP:Body>
|
|
2592
|
+
<Update xmlns="http://schemas.cordys.com/1.0/ldap">
|
|
2593
|
+
<tuple>
|
|
2594
|
+
<old>
|
|
2595
|
+
<entry dn="cn=sysadmin,cn=organizational users,o={organization},cn=cordys,cn=defaultInst,o=opentext.net">
|
|
2596
|
+
<role>
|
|
2597
|
+
<string>cn=everyoneIn{organization},cn=organizational roles,o={organization},cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2598
|
+
<string>cn=Administrator,cn=Cordys@Work,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2599
|
+
<string>cn=OTDS Push Service,cn=OpenText OTDS Platform Push Connector,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2600
|
+
</role>
|
|
2601
|
+
<description>
|
|
2602
|
+
<string>{user_name}</string>
|
|
2603
|
+
</description>
|
|
2604
|
+
<cn>
|
|
2605
|
+
<string>{user_name}</string>
|
|
2606
|
+
</cn>
|
|
2607
|
+
<objectclass>
|
|
2608
|
+
<string>top</string>
|
|
2609
|
+
<string>busorganizationalobject</string>
|
|
2610
|
+
<string>busorganizationaluser</string>
|
|
2611
|
+
</objectclass>
|
|
2612
|
+
<authenticationuser>
|
|
2613
|
+
<string>cn={user_name},cn=authenticated users,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2614
|
+
</authenticationuser>
|
|
2615
|
+
</entry>
|
|
2616
|
+
</old>
|
|
2617
|
+
<new>
|
|
2618
|
+
<entry dn="cn={user_name},cn=organizational users,o={organization},cn=cordys,cn=defaultInst,o=opentext.net">
|
|
2619
|
+
<role>
|
|
2620
|
+
<string>cn=everyoneIn{organization},cn=organizational roles,o={organization},cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2621
|
+
<string>cn=Administrator,cn=Cordys@Work,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2622
|
+
<string>cn=OTDS Push Service,cn=OpenText OTDS Platform Push Connector,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2623
|
+
<string>cn=Developer,cn=Cordys@Work,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2624
|
+
</role>
|
|
2625
|
+
<description>
|
|
2626
|
+
<string>{user_name}</string>
|
|
2627
|
+
</description>
|
|
2628
|
+
<cn>
|
|
2629
|
+
<string>{user_name}</string>
|
|
2630
|
+
</cn>
|
|
2631
|
+
<objectclass>
|
|
2632
|
+
<string>top</string>
|
|
2633
|
+
<string>busorganizationalobject</string>
|
|
2634
|
+
<string>busorganizationaluser</string>
|
|
2635
|
+
</objectclass>
|
|
2636
|
+
<authenticationuser>
|
|
2637
|
+
<string>cn={user_name},cn=authenticated users,cn=cordys,cn=defaultInst,o=opentext.net</string>
|
|
2638
|
+
</authenticationuser>
|
|
2639
|
+
</entry>
|
|
2640
|
+
</new>
|
|
2641
|
+
</tuple>
|
|
2642
|
+
</Update>
|
|
2643
|
+
</SOAP:Body>
|
|
2644
|
+
</SOAP:Envelope>
|
|
2645
|
+
"""
|
|
2646
|
+
retries = 0
|
|
2647
|
+
max_retries = 6
|
|
2648
|
+
retry_delay = 30 # Time in seconds
|
|
2649
|
+
|
|
2650
|
+
while retries < max_retries:
|
|
2651
|
+
try:
|
|
2652
|
+
response = requests.post(
|
|
2653
|
+
url=self.gateway_url(),
|
|
2654
|
+
data=cws_config_req_xml,
|
|
2655
|
+
headers=REQUEST_HEADERS,
|
|
2656
|
+
cookies=self.cookie(),
|
|
2657
|
+
timeout=30,
|
|
2658
|
+
)
|
|
2659
|
+
|
|
2660
|
+
if response.ok and role_name in response.text:
|
|
2661
|
+
self.logger.info("User '%s' successfully assigned the '%s' role.", user_name, role_name)
|
|
2662
|
+
return True
|
|
2663
|
+
|
|
2664
|
+
# Handle session expiration
|
|
2665
|
+
if response.status_code == 401 and retries == 0:
|
|
2666
|
+
self.logger.warning("Session expired. Re-authenticating...")
|
|
2667
|
+
self.authenticate(revalidate=True)
|
|
2668
|
+
retries += 1
|
|
2669
|
+
continue # Retry immediately after re-authentication
|
|
2670
|
+
|
|
2671
|
+
# Log failure response
|
|
2672
|
+
self.logger.error(
|
|
2673
|
+
"Failed to assign role to user '%s': HTTP %s - %s",
|
|
2674
|
+
user_name,
|
|
2675
|
+
response.status_code,
|
|
2676
|
+
response.text,
|
|
2677
|
+
)
|
|
2678
|
+
|
|
2679
|
+
except requests.RequestException:
|
|
2680
|
+
self.logger.error("Request failed:")
|
|
2681
|
+
|
|
2682
|
+
retries += 1
|
|
2683
|
+
self.logger.info("Retrying... Attempt %d/%d", retries, max_retries)
|
|
2684
|
+
time.sleep(retry_delay)
|
|
2685
|
+
|
|
2686
|
+
self.logger.error("Retry limit exceeded. Role assignment failed for user '%s'.", user_name)
|
|
2687
|
+
return False
|
|
2688
|
+
|
|
2689
|
+
# end method definition
|