Skip to content

Conversation

@BenWhitehead
Copy link
Collaborator

According to the official Javadocs, there is a contract that must exist between
#equals(Object)[1] and #hashCode()[2] for every class.

Prior to this change the contract was not upheld for the model classes due to
multiple reasons:

  1. Some classes did not define equals or hashCode instead relying on the default
    implementations from java.lang.Object
  2. Some classes were using different sets of fields between the two methods
  3. Some classes were not performing deep evaluation
  4. Some classes were serializing themselves to the apiary models before calling
    equals on the serialized instances

All model classes have been updated to ensure:

  1. They define an equals and hashCode
  2. The contract is upheld for these methods

Additionally, all internal usage of the deprecated DeleteRule has been removed
from BlobInfo. Instead, LifecycleRule are used exclusively. Deprecated
getDeleteRule and setDeleteRule have had their implementations changed to
perform an immediate conversion to/from LifecycleRule as necessary.

ApiaryConversions has been updated to ignore DeleteRule when encoding & decoding.

A codec for converting between DeleteRule <-> LifecycleRule has been added to
BackwardCompatibilityUtils. Corresponding tests for conversions between the
various types of DeleteRules have been added in BackwardCompatibilityUtilsTest.

Utils.ifNonNull has been updated to test the return value of the mapping
function before consuming it. Data.nullOf(Boolean.class) returns true
which can lead to unexpected behavior if a null value is provided to it
indirectly.

New Codec#andThen(Codec) has been added to allow easily connecting two Codecs.

[1] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-
[2] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--

@BenWhitehead BenWhitehead requested a review from a team as a code owner June 10, 2022 23:19
@product-auto-label product-auto-label bot added size: l Pull request size is large. api: storage Issues related to the googleapis/java-storage API. labels Jun 10, 2022
…d contract

According to the official Javadocs, there is a contract that must exist between
#equals(Object)[1] and #hashCode()[2] for every class.

Prior to this change the contract was not upheld for the model classes due to
multiple reasons:
1. Some classes did not define equals or hashCode instead relying on the default
   implementations from java.lang.Object
2. Some classes were using different sets of fields between the two methods
3. Some classes were not performing deep evaluation
4. Some classes were serializing themselves to the apiary models before calling
   equals on the serialized instances

All model classes have been updated to ensure:
1. They define an equals and hashCode
2. The contract is upheld for these methods

Additionally, all internal usage of the deprecated DeleteRule has been removed
from BlobInfo. Instead, LifecycleRule are used exclusively. Deprecated
getDeleteRule and setDeleteRule have had their implementations changed to
perform an immediate conversion to/from LifecycleRule as necessary.

ApiaryConversions has been updated to ignore DeleteRule when encoding & decoding.

A codec for converting between DeleteRule <-> LifecycleRule has been added to
BackwardCompatibilityUtils. Corresponding tests for conversions between the
various types of DeleteRules have been added in BackwardCompatibilityUtilsTest.

Utils.ifNonNull has been updated to test the return value of the mapping
function before consuming it. Data.<Boolean>nullOf(Boolean.class) returns `true`
which can lead to unexpected behavior if a null value is provided to it
indirectly.

New Codec#andThen(Codec) has been added to allow easily connecting two Codecs.

[1] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-
[2] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--
Copy link
Contributor

@frankyn frankyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, thanks for simplifying the story for deleteRules and lifecycleRules to have a single source

return Objects.equals(
Conversions.apiary().bucketInfo().encode(this),
Conversions.apiary().bucketInfo().encode(that));
return Objects.equals(generatedId, that.generatedId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test that can be added to check if all metadata values are set? This can be easily missed again.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like in general this is more of a "java best practice" to regenerate equals and hashcode when you add a property.

We may want to look into replacing the direct models with something generated in the future, which would automatically include all of the properties.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you be open to Autoclass?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, we'd have to investigate if it supported all the odd translations and hierarchies we need to support from a binary & source compatibility standpoint

@BenWhitehead BenWhitehead merged commit 0771936 into feat/grpc-storage Jun 16, 2022
@BenWhitehead BenWhitehead deleted the model-eq-hash branch June 16, 2022 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: storage Issues related to the googleapis/java-storage API. size: l Pull request size is large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants