forcedotcom / EMP-Connector

A simplified cometd connector for Enterprise Messaging Platform
BSD 3-Clause "New" or "Revised" License
185 stars 242 forks source link

Bulk subscriptions #7

Closed jackydec closed 7 years ago

jackydec commented 7 years ago

Would it be possible to add an Example Class that handles Bulk Subscriptions, mentionned in https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/using_streaming_api_bulk.htm ?

sfdc-hhildebrand commented 7 years ago

I'll take a look at batching. However, what is the use case for this? You still have to supply the consumers for each subscription, so I'm not sure what more there is here other than a loop over a list of {topic, consumer} pairs that just subscribe.

jackydec commented 7 years ago

the use case is that we want to have only one java-client that can handle multiple topics at once. Would it be possible to send a code snippet ?

sfdc-hhildebrand commented 7 years ago

So, handling multiple topics at once is currently supported. All you have to do is call EMPConnector.subscribe() with the new topic. Bayeux multiplexes the events down the same connection by default. So, you can subscribe and unsubscribe as many times as you like to as many topics as you like.

Does this solve your use case?

jackydec commented 7 years ago

Partially the case is indeed solved. I figured out how I could subscribe to multiple topics. I modified the LoginExample class as follows :

`Consumer<Map<String, Object>> consumer = event -> System.out.println(String.format("Received:\n%s", event)); EmpConnector connector = new EmpConnector(params);

    connector.start().get(5, TimeUnit.SECONDS);

    TopicSubscription subscription;
    subscription = connector.subscribe("/topic/InvoiceStatementUpdates", replayFrom, consumer).get(5, TimeUnit.SECONDS);
    subscription = connector.subscribe("/topic/AccountUpdates", replayFrom, consumer).get(5, TimeUnit.SECONDS);`

But : in order to process the results in our back-end database, I need to know the object for which i receive the events.

now, i receive the results as follows :

Received: {event={createdDate=2017-04-25T09:21:27.270Z, replayId=17, type=updated}, sobject={Id=a0G0L00000hw3z7UAA, Status__c=Open, Name=INV-0008}} Received: {event={createdDate=2017-04-25T09:20:57.126Z, replayId=11, type=updated}, sobject={Website=www.genepoint.com, NumberOfEmployees=265, Id=001E000000IOvcgIAD, Name=qsdfsdfsqdf}}

The events don't contain any data to what pushtopic or object they relate.

As a workaround, I could create a custom field in salesforce for each object I want to monitor through a pushtopic, containing the name of the object, but I wonder if there isn't a more elegant alternatif?

Any thoughts on that?

sfdc-hhildebrand commented 7 years ago

The problem is you are using the same consumer for all the topics. This will indeed cause confusion.

The solution pattern is to create a new consumer for each subscription. From the cometd topic, you know the push topic and thus the corresponding topic. If you wish to make this all automatic, what you'd do is use the Salesforce metadata apis to introspect all this to assemble and program your consumers. However interesting and cool such a thing would be, that certainly is beyond the scope of this humble connector.

Again, don't try to use one consumer for everything. it won't work. Rather, leverage the metadata already available to you via the rest of the Salesforce APIs and make a unique, programmable consumer for each stream.

jackydec commented 7 years ago

thanks for the advice, I will close the case.