def test_diff_with_changes(self): # Setup new = {"A": "AA", "B": "BBBB", "D": "DD"} old = {"A": "AA", "B": "BB", "C": "CC"} # Execute target = patch.OperationListBuilder() target.diff('/', old, new) result = target.get() # Verify expected = [{ 'op': patch.OperationListBuilder.OP_REPLACE, 'path': '/B', 'value': 'BBBB' }, { 'op': patch.OperationListBuilder.OP_ADD, 'path': '/D', 'value': 'DD' }, { 'op': patch.OperationListBuilder.OP_REMOVE, 'path': '/C' }] result_dict = {e['path']: e for e in result} expected_dict = {e['path']: e for e in expected} print 'EXPECTED', expected_dict print 'ACTUAL ', result_dict self.assertEquals(expected_dict, result_dict)
def get_rest_api_stage_update_patch_operations(current_stage, props): builder = patch.OperationListBuilder() if current_stage.get('cacheClusterEnabled', False) != props.CacheClusterEnabled: builder.replace('/cacheClusterEnabled', props.CacheClusterEnabled) if current_stage.get('cacheClusterSize', '') != props.CacheClusterSize: builder.replace('/cacheClusterSize', props.CacheClusterSize) builder.diff('/variables/', current_stage.get('variables', {}), props.StageVariables) # TODO: support MethodSettings. https://issues.labcollab.net/browse/LMBR-32185 # # See https://docs.aws.amazon.com/apigateway/api-reference/resource/stage/#methodSettings # for the paths needed to update these values. Note that the paths for these values have # the form /a~1b~1c/GET (slashes in the resource path replaced by ~1, and GET is any HTTP # verb). # # We can't remove individual values, we can only replace them with default values if they # aren't specified. However, if a path/method exists in current_stage but not in props, then # all the settings should be removed using a path like /a~1b~1c/GET. # # The wildcards may need some special handling. return builder.get()
def test_diff_nested_with_no_changes(self): # Setup new = {"Top": {"A": "AA", "B": "BB", "Nested": {"P": "PP"}}} old = {"Top": {"A": "AA", "B": "BB", "Nested": {"P": "PP"}}} # Execute target = patch.OperationListBuilder() target.diff('/', old, new) result = target.get() # Verify self.assertEquals(result, [])
def test_diff_nested_with_changes(self): # Setup new = { "Top": { "A": "AA", "B": "BBBB", "D": "DD", "Nested": { "P": "PP", "Q": "QQQQ", "S": "SS" } }, "NewTop": { "W": "WW", "X": "XXXX", "Z": "ZZ" } } old = { "Top": { "A": "AA", "B": "BB", "C": "CC", "Nested": { "P": "PP", "Q": "QQ", "R": "RR" } }, "OldTop": { "W": "WW", "X": "XX", "Y": "YY" } } # Execute target = patch.OperationListBuilder() target.diff('/', old, new) result = target.get() # Verify expected = [{ 'op': patch.OperationListBuilder.OP_REPLACE, 'path': '/Top/B', 'value': 'BBBB' }, { 'op': patch.OperationListBuilder.OP_REMOVE, 'path': '/Top/C' }, { 'op': patch.OperationListBuilder.OP_ADD, 'path': '/Top/D', 'value': 'DD' }, { 'op': patch.OperationListBuilder.OP_REPLACE, 'path': '/Top/Nested/Q', 'value': 'QQQQ' }, { 'op': patch.OperationListBuilder.OP_REMOVE, 'path': '/Top/Nested/R' }, { 'op': patch.OperationListBuilder.OP_ADD, 'path': '/Top/Nested/S', 'value': 'SS' }, { 'op': patch.OperationListBuilder.OP_ADD, 'path': '/NewTop/W', 'value': 'WW' }, { 'op': patch.OperationListBuilder.OP_ADD, 'path': '/NewTop/X', 'value': 'XXXX' }, { 'op': patch.OperationListBuilder.OP_ADD, 'path': '/NewTop/Z', 'value': 'ZZ' }, { 'op': patch.OperationListBuilder.OP_REMOVE, 'path': '/OldTop/W' }, { 'op': patch.OperationListBuilder.OP_REMOVE, 'path': '/OldTop/X' }, { 'op': patch.OperationListBuilder.OP_REMOVE, 'path': '/OldTop/Y' }] result_dict = {e['path']: e for e in result} expected_dict = {e['path']: e for e in expected} print 'EXPECTED', expected_dict print 'ACTUAL ', result_dict self.assertEquals(expected_dict, result_dict)
def get_rest_api_stage_update_patch_operations(current_stage, props): builder = patch.OperationListBuilder() if current_stage.get('cacheClusterEnabled', False) != props.CacheClusterEnabled: builder.replace('/cacheClusterEnabled', props.CacheClusterEnabled) if current_stage.get('cacheClusterSize', '') != props.CacheClusterSize: builder.replace('/cacheClusterSize', props.CacheClusterSize) builder.diff('/variables/', current_stage.get('variables', {}), props.StageVariables) # MethodSettings modifications - Set in your resource-template.json's ServiceApi Definition as: # "Properties": { # "MethodSettings": { # "/client/content": { # "POST": { # "throttlingBurstLimit": 177 # } # } # } # } # } settings_obj = current_stage.get('methodSettings', {}) existing_paths = [ curPath for curPath, curSettings in iteritems(settings_obj) ] props_settings = props.MethodSettings for path_str in dir(props_settings): path_info = getattr(props_settings, path_str) if not isinstance(path_info, properties._Properties): continue for requestVerb in dir(path_info): settings_path = path_str.replace('/', '~1') + '/' + requestVerb if settings_path in existing_paths: existing_paths.remove(settings_path) update_path = '/' + settings_path path_settings = getattr(path_info, requestVerb) if not isinstance(path_settings, properties._Properties): continue for method_base, method_update in [ ('throttlingBurstLimit', '/throttling/burstLimit'), ('throttlingRateLimit', '/throttling/rateLimit'), ('cacheDataEncrypted', '/caching/dataEncrypted'), ('cacheTtlInSeconds', '/caching/ttlInSeconds'), ('cachingEnabled', '/caching/enabled'), ('dataTraceEnabled', '/logging/dataTrace'), ('loggingLevel', '/logging/loglevel'), ('metricsEnabled', '/metrics/enabled') ]: cur_settings = settings_obj.get(settings_path, {}) cur_value = cur_settings.get(method_base, '') prop_value = getattr(path_settings, method_base) if cur_value != prop_value: builder.replace(update_path + method_update, str(prop_value)) for thisPath in existing_paths: builder.remove('/' + thisPath) return builder.get()