Skip to content

Conversation

@PrimosK
Copy link
Contributor

@PrimosK PrimosK commented Jul 13, 2021

Sprout for fix which downcasts parametrized nested IJsonBackedObject… objects during deserialization.

fixes #248 (sprout)

As deserialization of (nested) IJsonBackedObject is dependent based on the payload (Odata.type) the only way of doing it was to extend FallbackTypeAdapterFactory accordingly. So if Odata.type is present a new sub type adapter is created/used otherwise default Gson adapter is used.

As I am ATM short on time to look into this further I would highly appreciate if someone with the better overview of the related codebase would take it over from there.

All in all - I can confirm that this change fixes the issue observed in #248.

@ghost
Copy link

ghost commented Jul 13, 2021

CLA assistant check
All CLA requirements met.

@PrimosK PrimosK marked this pull request as draft July 13, 2021 12:21
Copy link
Member

@baywet baywet left a comment

Choose a reason for hiding this comment

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

thanks for starting to put all this together. I provided some initial feedback.

@baywet
Copy link
Member

baywet commented Jul 14, 2021

@PrimosK Also wanted to let you know about the following error from the api linting:

/home/runner/work/msgraph-sdk-java-core/msgraph-sdk-java-core/src/main/java/com/microsoft/graph/serializer/FallbackTypeAdapterFactory.java:133: Error: Access to private field logger of class FallbackTypeAdapterFactory requires synthetic accessor [SyntheticAccessor]
              this.derivedClassIdentifier = new DerivedClassIdentifier(logger);

@PrimosK
Copy link
Contributor Author

PrimosK commented Jul 16, 2021

Hi @baywet,

is there any progress with this pull request? Is there any further help needed?

One of the concerns I see (and could be improved) is the fact that adding new Type(Hiearchy)Adapter for IJsonBackedObject base type to (in the future):

https://github.com/PrimosK/msgraph-sdk-java-core/blob/59a3098489194d6446c1830e4c231517bf7aca25/src/main/java/com/microsoft/graph/serializer/GsonFactory.java#L331

... without adding it to:

https://github.com/PrimosK/msgraph-sdk-java-core/blob/59a3098489194d6446c1830e4c231517bf7aca25/src/main/java/com/microsoft/graph/serializer/FallbackTypeAdapterFactory.java#L103

... might result in unexpected behavior as com.microsoft.graph.serializer.FallbackTypeAdapterFactory.ODataTypeParametrizedIJsonBackedObjectAdapter might kick in instead.

With that in mind I wonder whether changing com.microsoft.graph.serializer.FallbackTypeAdapterFactory#create to something like this would be a better solution:

  public <T> TypeAdapter<T> create(@Nonnull final Gson gson, @Nonnull final TypeToken<T> type) {
      Objects.requireNonNull(type, "parameter type cannot be null");
      final Class<T> rawType = (Class<T>) type.getRawType();

      if (rawType.isEnum()) {
          return new EnumTypeAdapter<>(rawType, logger);
      } else if (rawType == Void.class) {
          return (TypeAdapter<T>) voidAdapter;
      } else if (IJsonBackedObject.class.isAssignableFrom(type.getRawType())) {

          final TypeAdapter<IJsonBackedObject> delegatedAdapter = (TypeAdapter<IJsonBackedObject>) gson.getDelegateAdapter(this, type);

          // Avoid overriding custom IJsonBackedObject type adapters defined in GsonFactory
          if (!(delegatedAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
              return null;
          }

          return (TypeAdapter<T>) new ODataTypeParametrizedIJsonBackedObjectAdapter(gson, delegatedAdapter, (TypeToken<IJsonBackedObject>) type, logger);
      }
      else {
          return null;
      }
  }

@baywet
Copy link
Member

baywet commented Jul 16, 2021

@PrimosK sorry, I thought you were still working on it since it's still in a draft state. When you are ready, please switch it from draft to open via the "ready to review" button.

The main missing thing I can see at this point are additional unit tests to test for the case we're fixing in this PR.

Having something dynamic that relies on the factory would probably be better indeed if the performance impact is not too high. This would prevent us from potentially shooting ourselves in the foot in the future. Thanks for considering it.

@PrimosK PrimosK marked this pull request as ready for review July 19, 2021 06:58
@PrimosK
Copy link
Contributor Author

PrimosK commented Jul 19, 2021

BTW - I guess I can't do nothing about static analysis with SonarCloud failing:

Execution failed for task ':sonarqube'.
You're not authorized to run analysis. Please contact the project administrator.

Copy link
Member

@baywet baywet left a comment

Choose a reason for hiding this comment

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

thanks for making changes, a few minor comments left.
And no, sonarqube requires access to a secret, and PRs from forks don't have access to secrets for security reasons, we'll run it once it gets merged.

PrimosK added 3 commits July 21, 2021 07:29
- DefaultSerializer
- CollectionResponseDeserializer
... as this is now taken care by ODataTypeParametrizedJsonBackedTypeAdapter.

Tests covering this change:
- com.microsoft.graph.serializer.DefaultSerializerTest.testDeserializationOfObjectWithODataTypeProperty
- com.microsoft.graph.serializer.ODataTypeParametrizedIJsonBackedTypedAdapterTest.testDeserializationOfNestedODataTypeAnnotatedObjects
@PrimosK
Copy link
Contributor Author

PrimosK commented Jul 21, 2021

I think that should be it.

In the future some improvements might be made also WRT:

com.microsoft.graph.serializer.IJsonBackedObject#setRawObject
com.microsoft.graph.serializer.IJsonBackedObject#additionalDataManager

.. being called from various places.

I think these could be simply called inside:

com.microsoft.graph.serializer.ODataTypeParametrizedIJsonBackedTypedAdapter#read

... but I am considering this a separate issue to keep the scope of this PR manageable.

Copy link
Member

@baywet baywet left a comment

Choose a reason for hiding this comment

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

LGTM! thanks for making all the adjustments! @ramsessanchez can you have a look as well please? and run a few tests locally?

@ramsessanchez ramsessanchez merged commit 29d9b8f into microsoftgraph:dev Jul 26, 2021
@baywet baywet added this to the 2.0.8 milestone Jul 27, 2021
@PrimosK
Copy link
Contributor Author

PrimosK commented Jul 27, 2021

It's nice to see that this fix was merged to 2.0.8. Are there any plans/approximations of when new 2.0.8 release will be out?

@baywet
Copy link
Member

baywet commented Jul 27, 2021

We'll probably take advantage of this release to test the migration of our release pipelines (last item in the milestone). The work has started on that, so let's have a tentative date by the end of next week. (ramses here just joined the team, and we need to account for the ramp-up)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EventMessageDetail - downcasting never kicks in

3 participants