Giter Club home page Giter Club logo

Comments (21)

jenschude avatar jenschude commented on June 15, 2024 1

If the event holds a Message the notificationType will be of type Message and the ISubscriptionDelivery will be deserialized correctly as a https://github.com/commercetools/commercetools-dotnet-core-sdk-v2/blob/master/commercetools.Sdk/commercetools.Sdk.Api/Generated/Models/Subscriptions/IMessageDelivery.cs

See also

public void DeserializationOfListOfMessageSubscriptionPayload()
{
ISerializerService serializerService = this.serializationFixture.SerializerService;
var expectedCategoryId = "3df866bd-7e5f-47d1-bbe2-ca1d1f39a260";
string serialized = File.ReadAllText("Resources/Messages/MessageSubscriptionPayload.json");
var payload = serializerService.Deserialize<ISubscriptionDelivery>(serialized);
Assert.NotNull(payload);
var categoryCreatedPayload = payload as MessageDelivery;
Assert.NotNull(categoryCreatedPayload);
Assert.Equal(expectedCategoryId, categoryCreatedPayload.Resource.Id);
var categoryCreatedMessage = serializerService.Deserialize<CategoryCreatedMessage>(serialized);
Assert.NotNull(categoryCreatedMessage);
Assert.Equal(expectedCategoryId, categoryCreatedMessage.Category.Id);
}

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024 1

Yes and it will be an instance of these classes:

[DefaultTypeDiscriminator(typeof(commercetools.Api.Models.Subscriptions.SubscriptionDelivery))]
[SubTypeDiscriminator("Message", typeof(commercetools.Api.Models.Subscriptions.MessageDelivery))]
[SubTypeDiscriminator("ResourceCreated", typeof(commercetools.Api.Models.Subscriptions.ResourceCreatedDelivery))]
[SubTypeDiscriminator("ResourceDeleted", typeof(commercetools.Api.Models.Subscriptions.ResourceDeletedDelivery))]
[SubTypeDiscriminator("ResourceUpdated", typeof(commercetools.Api.Models.Subscriptions.ResourceUpdatedDelivery))]

But you also can pattern match on the Interfaces

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024 1

Released 2.1.1 with the fix. Should be available in some minutes

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

Hi,

once you setup the subscriptions at commercetools. The platform will sent messages or events to your ServiceBus. If you configured it using the CloudEvents format you can deserialize the payload using any CloudEvents library for dotnet. If you have choosen platform format you should use the SDK Serializer to deserialize the payload to https://github.com/commercetools/commercetools-dotnet-core-sdk-v2/blob/master/commercetools.Sdk/commercetools.Sdk.Api/Generated/Models/Subscriptions/ISubscriptionDelivery.cs

More info about the delivery payload can be found here https://docs.commercetools.com/api/projects/subscriptions#delivery

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

In case you only need the serializerservice you can use the UseCommercetoolsApiSerialization method:

https://github.com/commercetools/commercetools-dotnet-core-sdk-v2/blob/master/commercetools.Sdk/commercetools.Sdk.Api/DependencyInjectionSetup.cs#L61

And then the ServiceProvider to retrieve a SerializerService instance

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Thank you, any chance to have a sample using your tools (ie SDK Serializer) to consume events ? I'm not familiar with this approach

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

Please see

public SerializationFixture()
{
var services = new ServiceCollection();
services.UseCommercetoolsApiSerialization();
var serviceProvider = services.BuildServiceProvider();
this.SerializerService = serviceProvider.GetService<SerializerService>();
}
public ISerializerService SerializerService { get; private set; }

to register the SerializationService to the ServiceProvider and

public void DeserializationOfResourceCreatedDelivery()
{
ISerializerService serializerService = this.serializationFixture.SerializerService;
string serialized = File.ReadAllText("Resources/Messages/ResourceCreatedPayload.json");
var payload = serializerService.Deserialize<ISubscriptionDelivery>(serialized);
Assert.NotNull(payload);
Assert.NotNull(payload.ResourceUserProvidedIdentifiers);
Assert.Equal("test-ca15403ea56ec0e51137ff40a6f4607e", payload.ResourceUserProvidedIdentifiers.Key);
Assert.IsType<ResourceCreatedDelivery>(payload);
var customerCreatedPayload = payload as ResourceCreatedDelivery;
Assert.NotNull(customerCreatedPayload);
Assert.NotNull(customerCreatedPayload.Resource);
Assert.IsType<CustomerReference>(customerCreatedPayload.Resource);
Assert.Equal("e63d76ff-e203-42ba-af17-375040b8ecb6", customerCreatedPayload.Resource.Id);
}

How to deserialize the payload

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Thank you for the sample/integration test.

I guess I misunderstood something, looking at the the "Resources/Messages/ResourceCreatedPayload.json" content and the ResourceCreatedDelivery/ResourceUpdatedDelivery/ResourceDeletedDelivery, the event doesn't transport data from the event itself (ie ECST), let's say a ProductCreatedMessage with its productProjection ?

Then is the recommandation to :

  • trigger on event consumption, deserialize as ResourceCreatedDelivery/ResourceDeleteDelivery/ResourceUpdatedDelivery object
  • detect wich entity is concerned by an action, then query it using the Messages Query HTTP API let's say using it's ID ?
  • the returned object is strongly typed ? (ie ProductCreatedMessage)

Am I right ?

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

If the event holds a Message the notificationType will be of type Message ...

I was missing this part, it's realy clear then. I guess we can apply pattern matching on

var payload = serializerService.Deserialize<ISubscriptionDelivery>(serialized);

right, (once its deserialized) ?

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Ok ! I guess it will be easier to deal with it once we'll have events to play with on the Bus.

Thank you very much for your time and explanations. If further questions come to me, do I have to reach the another communication channel (Jira, support email ...) ? or Github issue is fine ?

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

Questions regarding the SDK itself are fine to be asked at Github :)

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Thank you, I close the issue then. Have a good day

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

@jenschude I'm sorry to bother you again, but I played a bit with the tests from the lib to have a better understanding of how does it works, this part is critical for our own integration, so I have few more questions :

Correct me if I'm wrong, but as I understood, in the following test :

[Fact]
public void DeserializationOfListOfSubscriptionDelivery()
{
ISerializerService serializerService = this.serializationFixture.SerializerService;
string serialized = File.ReadAllText("Resources/Messages/Payloads.json");
var payloads = serializerService.Deserialize<List<ISubscriptionDelivery>>(serialized);
Assert.NotNull(payloads);
Assert.Equal(4, payloads.Count);
var resourceCreatedPayload = payloads[0] as ResourceCreatedDelivery;
var resourceUpdatedPayload = payloads[1] as ResourceUpdatedDelivery;
var resourceDeletedPayload = payloads[2] as ResourceDeletedDelivery;
var customerCreatedPayload = payloads[3] as MessageDelivery;

you deserialize the raw string as a List<ISubscriptionDelivery>, doing so you get typed objects for ResourceCreatedDelivery/ResourceUpdatedDelivery/ResourceDeletedDelivery (ie notificationType != "Message"). But for the fourth message ("notificationType": "Message" and "type": "CustomerCreated") the object is typed as a MessageDelivery , thus we can't access the strongly typed object (CustomerCreatedMessage) unless we do an explicit deserialization as you do in the next test :
public void DeserializationOfListOfMessageSubscriptionPayload()
{
ISerializerService serializerService = this.serializationFixture.SerializerService;
var expectedCategoryId = "3df866bd-7e5f-47d1-bbe2-ca1d1f39a260";
string serialized = File.ReadAllText("Resources/Messages/MessageSubscriptionPayload.json");
var payload = serializerService.Deserialize<ISubscriptionDelivery>(serialized);
Assert.NotNull(payload);
var categoryCreatedPayload = payload as MessageDelivery;
Assert.NotNull(categoryCreatedPayload);
Assert.Equal(expectedCategoryId, categoryCreatedPayload.Resource.Id);
var categoryCreatedMessage = serializerService.Deserialize<CategoryCreatedMessage>(serialized);

On the other hand deserializing str payload as IMessage (or as List<IMessage>) allows to access strongly typed messages without any extra deserialization

public void DeserializationOfListOfMessageSubscriptionPayloads()
{
ISerializerService serializerService = this.serializationFixture.SerializerService;
string serialized = File.ReadAllText("Resources/Messages/MessageSubscriptionPayloads.json");
var payloads = serializerService.Deserialize<List<IMessage>>(serialized);
Assert.NotNull(payloads);
Assert.IsType<CategoryCreatedMessage>(payloads[0]);
Assert.IsType<CustomerCreatedMessage>(payloads[1]);

But if any notificationType != "Message" is deserialized this way, the object is typed as a Message, and we don't have the information about its type (ResourceCreatedDelivery/ResourceUpdatedDelivery/ResourceDeletedDelivery).

Example with a mixed json ("notificationType": "Message" and "notificationType" != "Message")
image

  1. Considering a raw string consumed from the bus, am I supposed to try both ISubscriptionDelivery and IMessage deserializations to get my strongly typed event ? Or the subscribers to the bus expect to have filtered events coming in, then we can safely try to deserialize as ISubscriptionDelivery or as IMessage only as we will always receive the same kind of events from a subscriber perspective ?

  2. In the second test when

    var categoryCreatedMessage = serializerService.Deserialize<CategoryCreatedMessage>(serialized);

    How can you infer the T type ? Should we inspect the str payload itself ? Or is it for test purpose only and most of the time (always ?) we try to deserialize as IMessage directly ?

  3. What is the typical scenario of events beeing produced lets say when a Product is created on commercetools?
    Do we receive both "notificationType": "ResourceCreated" message and "notificationType": "Message" with "type": "ProductCreated" message ?
    Are there scenarii where we don't receive both ?
    As we'll react to these events, especially with data synchronization operations in our downstreams we have to know if we can 'ignore' notificationType" != "Message" for example, only dealing with notificationType" : "Message" or some use cases need to deal with both ?

  4. When the payload is not provided (PayloadNotIncluded != null), which API do we have to call to get it from a sync remote call ?

Again, thank you for your time

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Hi @jenschude
We plan to start the integration POC next week, we are currenlty following the 'Functional Training Session' (with Calvin and Michael).
Well do I need to switch to a more 'official' channel, as we bought an official licence ? Or is it part of the '.net SDK Training' that I should ask my questions ? Indeed we would like to avoid bad practices and follow your guidelines as much as possible, it'll save us time.
So if you've some time to deal with my questions, many thanks

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

Oh man I now took a closer look and found a hole in the logic as the Message is not unmarshalled when using the MessageDelivery. Next week we can fix this and also extend the tests with some different use cases. Nevertheless the deserialization depends on the type of the Subscription and can be simplified if necessary

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

Btw when using Azure you could also use the CloudEvents format instead of the platform format. Especially as Azure already comes with native CloudEvents support. The data payload of the Event would then be the Message and you could use the SerializerService to deserialize it to the respective class instance

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

@jenschude

Thank you for your feedback (and running PR).
Well with this fix, when do you try to deserizalize the Azure Service Bus raw string as ISubscriptionDelivery rather than IMessage ? Should we inspect the raw string on some existing field to choose ?
We basically need the event carrying data that has been produced from the mutation in CT.

It's not clear to me in which case you use one rather than another

Thank you

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

This is what the CloudEvent payload for a Message subscription would look like.

To my knowlegde there is a CloudEvent library available from Azure which could be used to deserialize this payload. The data field itself could then be mapped to the IMessage interface, as the delivery related fields are included in the cloud event itself.

           {
             "specversion": "1.0",
             "id" : *any-uuid*,
             "type" : "com.commercetools.product.message.ProductPublished",
             "source" : "/<project-key>/products",
             "subject" : "<product-id>",
             "time" : *any-date-time*,
             "sequence" : "3",
             "sequencetype" : "Integer",
             "dataref": "/<project-key>/messages/<msg-id>",
             "data": {
               "notificationType": "Message",
               "projectKey": "<project-key>",
               "version": 1,
               "sequenceNumber": 3,
               "resource": {
                 "typeId": "product",
                 "id": "<product-id>"
               },
               "resourceUserProvidedIdentifiers": {
                 "key": "subscription-product",
                 "slug": <product-slug>
               },
               "removedImageUrls": [],
               "productProjection": {
                 "id": "<product-id>",
                 "version": 4,
                 "productType": {
                   "typeId": "product-type",
                   "id": "<product-type-id>"
                 },
                 "categories": [],
                 "categoryOrderHints": {},
                 "searchKeywords": {},
                 "hasStagedChanges": false,
                 "published": true
               },
               "resourceVersion": 4,
               "type": "ProductPublished"
             }
           }

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Ok we'll try both approachs : raw string and CloudEvent messages and see what best suits our needs.
But both should produces the same deserialized object, doesn't it ?

from commercetools-dotnet-core-sdk-v2.

jenschude avatar jenschude commented on June 15, 2024

They should as the json structure is the same.

The nice thing about the CloudEvents format would be, that you could route the events in the Azure Event Grid natively.

from commercetools-dotnet-core-sdk-v2.

NicolasREY69330 avatar NicolasREY69330 commented on June 15, 2024

Yes, and it gives a formalism.
Well the 'auto routing' events is a great, but my final sink is Kafka :-/

from commercetools-dotnet-core-sdk-v2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.