-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GEOT-7559] App-Schema throws an error when mappings have duplicate names, even when they come from includes #4730
[GEOT-7559] App-Schema throws an error when mappings have duplicate names, even when they come from includes #4730
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx @turingtestfail, I add some review comments.
@@ -121,6 +121,9 @@ public class AppSchemaDataAccessConfigurator { | |||
|
|||
public static final String PROPERTY_REPLACE_OR_UNION = "app-schema.orUnionReplace"; | |||
|
|||
/** Whether the mapping is for an include. */ | |||
private final Boolean isInclude; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering, do we have a reason to make the isInclude optional? I guess by default we could assume false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were a lot of tests that have calls to the method so to avoid a lot of rewrites I overloaded the method with this as an argument. The latest push switched it to have an Optional wrapper to make it more explicit. Does that work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched to plain boolean primitive type with default of false.
@@ -169,6 +179,57 @@ public AppSchemaDataAccess(Set<FeatureTypeMapping> mappings, boolean hidden) | |||
register(); | |||
} | |||
|
|||
/** | |||
* Checks if the mapping is an include and is identical to the previous one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest adding more details to this method, along the lines of:
If the provided feature type mapping does not result from an include directive, we return false immediately. We then check if a previous mapping has already been registered for the provided feature type name. If that's the case, we verify if the new provided mapping is deeply equal to the already registered one. If this comparison holds true, we return true.
The objective here is to ensure that if a feature type mapping has already included this specific feature type mapping, it is indeed the same mapping definition. The intention is to prevent different mappings for the same feature type from coexisting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments added
} | ||
FeatureTypeMapping compareMapping = null; | ||
// Get the mapping to compare with | ||
if (mapping.getMappingName() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If my memory serves me well, in App-Schema, a feature type mapping is identified by the target element's qualified name, or optionally by the mapping name. The typical scenario involves defining a mapping for a target element, and that's usually sufficient. However, there are certain scenarios where we might require different mappings for the same target element. In such cases, we can provide a mapping name to disambiguate between them.
The current logic appears to rely solely on the presence of a mapping name, which is optional. This implies that include types must mandatorily have a mapping name, which is not the case. Therefore, I would suggest reviewing the logic to search for corresponding mappings by using the provided mapping name if available, and if not, by the target element.
I assume that currently, if two different mappings include the same mapping without defining a mapping name, it would raise a complaint about a duplicate mapping for the same target element. This PR aims to rectify such issues, assuming my understanding is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added logic to check of target element.
+ " while trying to test for duplicates"); | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm uncertain about this aspect, but if my understanding is accurate, the objective is to prevent App-Schema from raising errors about duplicate mappings when the exact same feature type mapping is encountered multiple times due to being included by different mappings.
It appears that we're conducting a search in two different places:
- Firstly, in the mappings hashmap of this
AppSchemaDataAccess
instance. I presume that anAppSchemaDataAccess
instance is associated with a root mapping in App-Schema. - Secondly, in the
DataAccessRegistry
registry, which encompasses all the root mappings registered in App-Schema.
The search for duplicates encompasses both:
if (this.mappings.containsKey(name) || DataAccessRegistry.hasName(name)) {
I would suggest adding comments in the code to elucidate the process. It seems that the initial check is performed within the current mappings, as if the mapping is found there, it implies it has already been validated against the common registry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments added.
FeatureTypeMapping mapping, FeatureTypeMapping compareMapping) { | ||
if (mapping == compareMapping) return true; | ||
return Objects.equals(mapping.getAttributeMappings(), compareMapping.getAttributeMappings()) | ||
&& Objects.equals(mapping.getMappingName(), compareMapping.getMappingName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same comment applies here as above. So, it's not only the mapping name, which is optional, but we also need to check the target element name.
That said, should we also check for other properties of the mappings? Such as data sources, normalization, etc.? Would it make more sense to implement this equality check in the FeatureTypeMapping class itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Target check added. Data source id and normalization comparisons added. Previously this was the equals method in FeatureTypeMapping but the accompanying hash method was causing test failures so I moved it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I just pushed a version with the logic moved to the equals method in FeatureTypeMapping and a corrected hash method and the tests are passing.
054a5a5
to
172088e
Compare
…ames, even when they come from includes deep equality trimmed down fixed equality compare and started on test Cleanup more cleanup moved equal to local PR responses moved to equals switch to primitive boolean
172088e
to
ca597fb
Compare
This PR may be failing GeoServer builds due to an API change in AppSchemaDataAccessConfigurator: |
Yes, was made aware of that today. This PR provides a fix on the GeoServer
side:
geoserver/geoserver#7633
…On Mon, May 20, 2024 at 12:20 PM Steve Ikeoka ***@***.***> wrote:
This PR may be failing GeoServer builds due to an API change in
AppSchemaDataAccessConfigurator:
Error: 8,713 [ERROR]
/home/runner/work/geoserver/geoserver/src/community/smart-data-loader/src/main/java/org/geoserver/smartdataloader/data/SmartDataLoaderDataAccessFactory.java:[205,74]
incompatible types: org.geotools.data.complex.config.DataAccessMap cannot
be converted to boolean
—
Reply to this email directly, view it on GitHub
<#4730 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHRJZ4XLT2X2GPPOTEG24YTZDIPGHAVCNFSM6AAAAABGXGR3WSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRQG43TSMJVHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
deep equality trimmed down
fixed equality compare and started on test
Cleanup
more cleanup
moved equal to local
Checklist
main
branch (backports managed later; ignore for branch specific issues).For core and extension modules:
[GEOT-XYZW] Title of the Jira ticket
.