openrewrite / rewrite

Automated mass refactoring of source code.
https://docs.openrewrite.org
Apache License 2.0
2.2k stars 329 forks source link

Problem when combining recipes (ChangePropertyKey and DeleteProperty) that modify properties of type "Map with values" #1102

Closed josemariavillar closed 3 years ago

josemariavillar commented 3 years ago

Good afternoon,

I am observing a strange behavior when combining different recipes, specifically DeleteProperty and ChangePropertyKey. If I set the following recipe:

---
type: specs.openrewrite.org/v1beta/recipe
name: darwin.example.Migrate
displayName: Migrate Example
description: 'Migrate properties found in `application.properties` and `application.yml`.'
recipeList:
  - org.openrewrite.yaml.DeleteProperty:
      propertyKey: es.santander.nuar.util.security.omnichannel
      coalesce: false
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.external-channel-map
      newPropertyKey: darwin.omnichannel.external-channel-map
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.security.filter-order
      newPropertyKey: darwin.omnichannel.security.filter-order
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.header
      newPropertyKey: darwin.omnichannel.header.channel
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.parameter
      newPropertyKey: darwin.omnichannel.parameter.channel

on the following YAML:

es:
  santander:
    nuar:
      util:
        security:
          omnichannel:
            OFI:
              pkm: https://pkm-ofi/v1/publicKey
              sts: https://sts-ofi/
        omnichannel:
          external-channel-map:
            ALL:
              OFI:
                marco-channel: OFI_W
                environment: INTRANET_Z
          security:
            filter-order: 100
          parameter: "channel"
          header: "X-Santander-Channel"

the obtained result is the correct one:

darwin.omnichannel.external-channel-map.ALL.OFI:
            marco-channel: OFI_W
            environment: INTRANET_Z
darwin.omnichannel.security.filter-order: 100
darwin.omnichannel.header.channel: "X-Santander-Channel"
darwin.omnichannel.parameter.channel: "channel"

But, if we set the "coalesce" property of the DeleteProperty to "true" the result, instead, is not the expected one, the property "en.santander.nuar.util.omnichannel.external-channel-map" does not change:

es.santander.nuar.util.omnichannel.external-channel-map.ALL.OFI:
marco-channel: OFI_W
environment: INTRANET_Z
darwin.omnichannel.security.filter-order: 100
darwin.omnichannel.header.channel: "X-Santander-Channel"
darwin.omnichannel.parameter.channel: "channel"

If now, we change the order of the recipes and the DeleteProperty recipe to put it at the end, the result is different:

---
type: specs.openrewrite.org/v1beta/recipe
name: darwin.example.Migrate
displayName: Migrate Example
description: 'Migrate properties found in `application.properties` and `application.yml`.'
recipeList:
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.external-channel-map
      newPropertyKey: darwin.omnichannel.external-channel-map
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.security.filter-order
      newPropertyKey: darwin.omnichannel.security.filter-order
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.header
      newPropertyKey: darwin.omnichannel.header.channel
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel.parameter
      newPropertyKey: darwin.omnichannel.parameter.channel
  - org.openrewrite.yaml.DeleteProperty:
      propertyKey: es.santander.nuar.util.security.omnichannel
      coalesce: false

In this case, as we can see, the DeleteProperty recipe is not executed and does not delete the property "en.santander.nuar.util.security.omnichannel" regardless of whether the "coalesce" is set to false or true:

es.santander.nuar.util.security.omnichannel.OFI:
pkm: https://pkm-ofi/v1/publicKey
sts: https://sts-ofi/
darwin.omnichannel.external-channel-map.ALL.OFI:
            marco-channel: OFI_W
            environment: INTRANET_Z
darwin.omnichannel.security.filter-order: 100
darwin.omnichannel.header.channel: "X-Santander-Channel"
darwin.omnichannel.parameter.channel: "channel"

Can you tell me, please, what could be happening and if I am misapplying any recipe. I have the suspicion that the problem occurs when combining recipes with properties of type "Map with values".

Thank you very much

traceyyoshima commented 3 years ago

Hi @josemariavillar, thanks for reporting the issue!

I'd recommend a slightly different approach:

---
type: specs.openrewrite.org/v1beta/recipe
name: darwin.example.Migrate
displayName: Migrate Example
description: 'Migrate properties found in `application.properties` and `application.yml`.'
recipeList:
  - org.openrewrite.yaml.DeleteProperty:
      propertyKey: es.santander.nuar.util.security.omnichannel.OFI
      coalesce: true
  - org.openrewrite.yaml.ChangePropertyKey:
      oldPropertyKey: es.santander.nuar.util.omnichannel
      newPropertyKey: darwin.omnichannel

Using coalensce on DeleteProperty will bring es.santander.nuar.util.security.omnichannel: up to the root and remove the target entry.

# result
es.santander.nuar.util.omnichannel:
  external-channel-map.ALL.OFI:
    marco-channel: OFI_W
    environment: INTRANET_Z
  security.filter-order: 100
  parameter: "channel"
  header: "X-Santander-Channel"

Then ChangePropertyKey will update the key to what you'd like:

darwin.omnichannel:
  external-channel-map.ALL.OFI:
    marco-channel: OFI_W
    environment: INTRANET_Z
  security.filter-order: 100
  parameter: "channel"
  header: "X-Santander-Channel"

Please let me know if you have any questions, thanks again.

Just a cool tip if you don't know, postfixing ``` with a language will enable syntax highlighting :) examples: ```java, ```yaml

traceyyoshima commented 3 years ago

@josemariavillar Thanks again for reaching out!