1
1
# pylint: disable=import-outside-toplevel
2
2
# pylint: disable=R0904
3
- # have to skip B404, import_subprocess is required for executing typescript
4
- # have to skip B60*, to allow typescript code to be executed using subprocess
5
3
import json
6
4
import logging
7
5
import re
8
- import subprocess # nosec
9
- import tempfile
10
6
import time
11
7
from time import sleep
12
8
from uuid import uuid4
13
9
14
10
import docker
15
11
from botocore import UNSIGNED
16
12
from botocore .config import Config
17
- from jinja2 import Environment , PackageLoader , select_autoescape
18
13
19
14
from rpdk .core .contract .interface import Action , HandlerErrorCode , OperationStatus
20
15
from rpdk .core .exceptions import InvalidProjectError
@@ -181,13 +176,6 @@ def _properties_to_paths(self, key):
181
176
182
177
def _update_schema (self , schema ):
183
178
# TODO: resolve $ref
184
- self .env = Environment (
185
- trim_blocks = True ,
186
- lstrip_blocks = True ,
187
- keep_trailing_newline = True ,
188
- loader = PackageLoader (__name__ , "templates/" ),
189
- autoescape = select_autoescape (["html" , "htm" , "xml" , "md" ]),
190
- )
191
179
self ._schema = schema
192
180
self ._strategy = None
193
181
self ._update_strategy = None
@@ -198,14 +186,12 @@ def _update_schema(self, schema):
198
186
self .write_only_paths = self ._properties_to_paths ("writeOnlyProperties" )
199
187
self .create_only_paths = self ._properties_to_paths ("createOnlyProperties" )
200
188
self .properties_without_insertion_order = self .get_metadata ()
201
- self .property_transform_keys = self ._properties_to_paths ("propertyTransform" )
202
- self .property_transform = self ._schema .get ("propertyTransform" )
189
+
203
190
additional_identifiers = self ._schema .get ("additionalIdentifiers" , [])
204
191
self ._additional_identifiers_paths = [
205
192
{fragment_decode (prop , prefix = "" ) for prop in identifier }
206
193
for identifier in additional_identifiers
207
194
]
208
- self .transformation_template = self .env .get_template ("transformation.template" )
209
195
210
196
def has_only_writable_identifiers (self ):
211
197
return all (
@@ -233,119 +219,6 @@ def get_metadata(self):
233
219
and properties [prop ]["insertionOrder" ] == "false"
234
220
}
235
221
236
- def transform_model (self , input_model , output_model ): # pylint: disable=R0914
237
- if self .property_transform_keys :
238
- self .check_npm ()
239
- for prop in self .property_transform_keys : # pylint: disable=R1702
240
- try :
241
- document_input , _path_input , _parent_input = traverse (
242
- input_model , list (prop )[1 :]
243
- )
244
- document_output , _path_output , _parent_output = traverse (
245
- output_model , list (prop )[1 :]
246
- )
247
- if not self .compare (document_input , document_output ):
248
- path = "/" + "/" .join (prop )
249
- property_transform_value = self .property_transform [path ].replace (
250
- '"' , '\\ "'
251
- )
252
- if "$OR" in property_transform_value :
253
- transform_functions = property_transform_value .split ("$OR" )
254
- for transform_function in transform_functions :
255
- transformed_property = self .transform (
256
- transform_function , input_model
257
- )
258
- value = self .convert_type (
259
- document_input , transformed_property
260
- )
261
- if self .compare (value , document_output ):
262
- self .update_transformed_property (
263
- prop , value , input_model
264
- )
265
- else :
266
- transformed_property = self .transform (
267
- property_transform_value , input_model
268
- )
269
- value = self .convert_type (document_input , transformed_property )
270
- self .update_transformed_property (prop , value , input_model )
271
-
272
- except KeyError :
273
- pass
274
-
275
- @staticmethod
276
- def convert_type (document_input , transformed_property ):
277
- if isinstance (document_input , bool ):
278
- return bool (transformed_property )
279
- if isinstance (document_input , int ):
280
- return int (transformed_property )
281
- if isinstance (document_input , float ):
282
- return float (transformed_property )
283
- return transformed_property
284
-
285
- @staticmethod
286
- def compare (document_input , document_output ):
287
- try :
288
- if isinstance (document_input , str ):
289
- return bool (re .match (f"^{ document_input } $" , document_output ))
290
- return document_input == document_output
291
- except re .error :
292
- return document_input == document_output
293
-
294
- def transform (self , property_transform_value , input_model ):
295
- LOG .debug ("This is the transform %s" , property_transform_value )
296
- content = self .transformation_template .render (
297
- input_model = input_model , jsonata_expression = property_transform_value
298
- )
299
- LOG .debug ("This is the content %s" , content )
300
- file = tempfile .NamedTemporaryFile (
301
- mode = "w+b" ,
302
- buffering = - 1 ,
303
- encoding = None ,
304
- newline = None ,
305
- suffix = ".js" ,
306
- prefix = None ,
307
- dir = "." ,
308
- delete = True ,
309
- )
310
- file .write (str .encode (content ))
311
-
312
- LOG .debug ("Jsonata transformation content %s" , file .read ().decode ())
313
- jsonata_output = subprocess .getoutput ("node " + file .name )
314
-
315
- file .close ()
316
- return jsonata_output
317
-
318
- # removing coverage for this method as it is not possible to check both npm
319
- # exists and does not exist condition in unit test
320
- @staticmethod
321
- def check_npm (): # pragma: no cover
322
- output = subprocess .getoutput ("npm list jsonata" )
323
- if "npm: command not found" not in output :
324
- if "jsonata@" not in output :
325
- subprocess .getoutput ("npm install jsonata" )
326
- else :
327
- err_msg = (
328
- "NPM is required to support propertyTransform. "
329
- "Please install npm using the following link: https://www.npmjs.com/get-npm"
330
- )
331
- LOG .error (err_msg )
332
- raise AssertionError (err_msg )
333
-
334
- @staticmethod
335
- def update_transformed_property (property_path , transformed_property , input_model ):
336
- try :
337
- _prop , resolved_path , parent = traverse (
338
- input_model , list (property_path )[1 :]
339
- )
340
- except LookupError :
341
- LOG .debug (
342
- "Override failed.\n Path %s\n Document %s" , property_path , input_model
343
- )
344
- LOG .warning ("Override with path %s not found, skipping" , property_path )
345
- else :
346
- key = resolved_path [- 1 ]
347
- parent [key ] = transformed_property
348
-
349
222
@property
350
223
def strategy (self ):
351
224
# an empty strategy (i.e. false-y) is valid
@@ -518,7 +391,7 @@ def make_request(
518
391
creds ,
519
392
token ,
520
393
callback_context = None ,
521
- ** kwargs ,
394
+ ** kwargs
522
395
):
523
396
return {
524
397
"requestData" : {
@@ -594,7 +467,7 @@ def _make_payload(self, action, current_model, previous_model=None, **kwargs):
594
467
self ._session , LOWER_CAMEL_CRED_KEYS , self ._role_arn
595
468
),
596
469
self .generate_token (),
597
- ** kwargs ,
470
+ ** kwargs
598
471
)
599
472
600
473
def _call (self , payload ):
0 commit comments