We are publish message i.e brokered message object with body content type "string" to window server service bus on topics and pulling the message from topic/subscription using WCF service. all the example we have seen on the internet uses Action attribute with "" on operationcontract/servicemethod , why do we need to mark as action "" while using netmessagebinding ?
When you have a service contract with multiple operations, the SOAP action header value is used to identify which operation is being invoked through the input message. In the NetMessageBinding case, the input message is not a SOAP message itself, so there will be no SOAP action value that can be used to dispatch the operation.
To work around that, WCF allows you to define "catch-all" operations, by marking them with Action="*", which means that any message that was not explicitly routed to some operation through the normal mechanics will be dispatched to the catch-all operation.
So, in essence, what you're doing here is telling WCF to process all incoming messages through this operation in the service contract.
Related
As I have been able to verify, in MassTransit with Azure Service Bus, each type of object consumed by a "Consumer" generates a Topic for that type regardless of whether it is only consumed in a specific "receive endpoint" (queue). When sending a message of this type with the "Send()" method, the message is sent directly to the "receive endpoint" (queue) without going through the topic. If this same message is published with the "Publish()" method, it is published in the Topic, and is forwarded to the receive endpoint (queue) from the corresponding subscriber.
My application uses a CQRS pattern where the messages are divided into commands and events. Commands use the send-receive pattern and are therefore always dispatched in MassTransit with the "Send()" method. The events, however, are based on the publish-subscribe pattern, and therefore are always dispatched in MassTransit with the "Publish()" method. As a result, a large number of topics are created on the bus that are never used (one for each type of command), since the messages belonging to these topics are sent directly to the receiver's queue.
For all these reasons, the question I ask is whether it is possible to configure MassTransit so that it does not automatically create the topics of some types of messages consumed because they will only be sent using the "Send()" method? Does this make sense in MassTransit or is it not possible/recommended?
Thank you!
Regards
Edited 16/04/2021
After doing some testing, I edit this topic to clarify that the intention is to configure MassTransit so that it does not automatically create the topics of some types of messages consumed, all of them received on the same receive endpoint. That is, the intention is to configure (dynamically if possible, through the type of object) which types of messages consumed create a topic and which do not in the same receive endpoint. Let's imagine that we have a receive endpoint (a queue) associated with a service, and this service is capable of consuming both commands and events, since the commands are only dispatched through Send(), it is not necessary to create the topic for them, however the events that are dispatched via Publish(), they need their topic (and their subscribers) to exist in order to deliver the message and be consumed.
Thanks in advance
Yes, for a receive endpoint hosting a consumer that will only receive Sent messages, you can specify ConfigureConsumeTopology = false for that receive endpoint. You can do that via a ConsumerDefinition, or when configuring the receive endpoint directly.
UPDATE
It is also possible to disable topology configuration per message type using an attribute on the message contract:
[ConfigureConsumeTopology(false)]
public interface SomeCommand
{
}
This will prevent the topic/exchange from being created and bound to the receive endpoint.
While I can understand the desire to be "pure to the CQRS mantra" and only Send commands, I'd suggest you read this answer and take it into consideration before overburdening your developers with knowing every single endpoint in the system by name...
Take the following sample requirement:
Service A does some work. That work is done periodically and no one asks Service A to do it. It's done automatically.
Service B needs to query data produced by Service A. Service A resides in a different server than Service B.
That is, Service B won't be able to get data if Service A doesn't provide some way of asking it for the data.
I want to require Service A data the SOA way using RabbitMQ: when Service B requires some data, it sends a message to a given exchange and its written to some queue. Then, Service A processes the message and publishes the answer to some other exchange. Finally, Service B listens the answer message and the cycle ends.
My question
I need some way to both publish and consume messages identified by the operation that requested data to Service A, and I also need that each started operation could be identified by an unique identifier.
My question is about how to publish a message and be able to receive an answer for a particular invocation of an operation.
I just want to validate that RabbitMQ routing keys are the answer to this requirement. For example, Service A sends a message with a routing key 072e6ee1-6046-4c3b-bade-9077c863637b. There's a consumer in Service B which consumes any message ignoring the routing key, but once it produces a result, it does publishing a message to an exchange with the same routing key . Therefore, Service A receives message because it's bound to the whole routing key.
Is it a possible right usage of routing keys?
This doesn't seem to be the correct way to use routing keys, if I understand you correctly. Routing keys tend to be used to define an operation, eg 'do-this' or 'do-that' - I wouldn't expect them to contain keys, unless those keys were a limited set that defined how the system operates. The Ids that you mention (they seem to be correlation Ids, so that you can match a received response to an outbound request, asynchronously) would be contained in the body of the message. So, you have the following setup:
Service B -> send message to exchange with routing key 'process-data'. The message contains the Id in its body.
Service A listens to messages on Queue A, which is is bound to the exchange with binding key 'process-data'. It then dequeue's Service B's message, whose body contains the Id
Service A performs processing
Service A -> send message to exchange with routing key 'data-processed'. The message contains the original Id in its body.
Service B listens to messages on Queue B, which is is bound to the exchange with binding key 'data-processed'. It then dequeue's Service A's message, whose body contains the Id
Finally, RabbitMQ already provides a solution to solve my scenario: Remote Procedure Calls tutorial.
At the end of the day, a message can have correlation id and a reply to fields:
Correlation id. An arbitrary value used to uniquely-identify an operation across many exchanges/queues.
Reply to. An arbitrary string to define on which exchange or queue you want to put the result of a given operation. The target exchange/queue will be the callback information that will be received by the operation.
Thus, Service A sends a message to a given exchange with a correlation id and a reply to value. It gets subscribed to reply to exchange. When Service B processes the message it publishes a message to the reply to exchange and Service A receives the whole result.
BTW, I still have some concerns about this model, because you need to receive callback messages from other operations while you wait for the result, and whenever you consume a message that's not marked with desired correlation id, you simply don't process it and you wait for the next one, and so on, until you get what you want.
Maybe it might be a good idea that callback messages would be queued with a time-to-live so if who started an operation isn't waiting for the callback anymore, a given callback message would be automatically dropped.
Another approach would be throwing the callback information as a document or record in a SQL/NoSQL database, and poll the database with an indexed query by callback identifier...
If I find some other approach using RabbitMQ I'll update my answer.
I understand ESB has in-sequence, out sequence and fault sequence, Is in-sequence same as main sequence ?
Also I would like to know if we define receive sequence in a endpoint will it override default behaviour and response is handled by specified received sequence ? Will response handled by default sequence if received sequence is not specified explicitly ?
Most of the WSO2 ESB examples in internet are based on proxy service, I would like to understand how sequence can be used without proxy service, Can you please introduce me to a such tutorial ?
Triggering Messages
Messages come into the ESB through the following triggers:
A proxy service receives messages that have been sent to a specific endpoint.
A task injects a message into the ESB at a scheduled interval.
A REST API call sends a message to the ESB.
When the ESB receives a message, it sends it either to a proxy service or to the Main sequence for handling. The proxy or sequence is configured with message mediation, which controls how the message will be transformed, filtered, forwarded, etc.
To trigger messages in the ESB, see the following topics:
Creating APIs
Working with Proxy Services
Working with Tasks
Using REST
Source = https://docs.wso2.com/display/ESB481/Triggering+Messages
About the Main and Fault Sequences
A mediation configuration holds two special sequences named main and fault. All messages that are not destined for Proxy Services are sent through the main sequence. By default, the main sequence simply sends a message without mediation, so to add message mediation, you add mediators and/or named sequences in the main sequence.
By default, the fault sequence will log the message, the payload, and any error/exception encountered, and the drop mediator stops further processing. You should configure the fault sequence with the correct error handling instead of simply dropping messages. For more information, see Error Handling.
Source = https://docs.wso2.com/display/ESB481/Mediation+Sequences#MediationSequences-mainSequence
Also I would like to know if we define receive sequence in a endpoint will it override default behaviour and response is handled by specified received sequence ? Will response handled by default sequence if received sequence is not specified explicitly ?
Correct , in a proxy though , and the default behaviour is to send to "out sequence"
I am also a beginner at this , just know what I know through (a lot of) trial and error ;)
Ok so assuming you have a default offset of 0 , you're ESB instance should have 2 default transports/ports :
HTTP = 8280
HTTPS = 8243
So , any message sent to these ports will reach the main sequence , UNLESS , they are service specific endpoints, so for example , for a soap message with endpoint :
http://localhost:8280
this will reach the default main sequence , and the following
https://localhost:8243/services/yourProxyService ,
will got to the in sequence of the yourProxyService.
Also , in [esb_home]/repository/conf/log4j.properties , set/uncomment the following lines :
log4j.logger.httpclient.wire.header=DEBUG
log4j.logger.httpclient.wire.content=DEBUG
log4j.category.org.apache.synapse=DEBUG ,
this should show you much more info in the log and make it easier to know which sequence you are in..
feel free to ask me other stuff , cool
As far as I understand if I click canCreateInstance, then for each request that comes to the service, there is created a new thread and that request is executed immediately.
If canCreateInstance is disabled, then the requests will be put in a queue and they will be processed one at a time.
Is this correct? I am implementing a queue with canCreateInstance disabled. Do you know anything against something like this? How Can I start the service with canCreateInstance disabled
Given a WorkflowServiceHost receives a message matching the contract and operation name for the initial receive activity
If CanCreateInstance is true then WorkflowServiceHost will create a new instance of the workflow and deliver the message to the receive activity.
If CanCreateInstance is false then the WorkflowServiceHost will throw an exception
There is no context attached to the incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized.
The first receive activity in the workflow should always have CanCreateInstance = true otherwise the workflow cannot activate.
The reason this property exists is so we can have one Receive activity that works for both activating receives and continuing receives.
My WCF service(hosted as Windows Service), has some 'SendEmail' methods, which sends out emails after doing some processing.
Now, I have got another requirement where client wants to preview emails before they are being sent out, so my WCF service needs to return whole email object to calling web app.
If client is happy with emails object, they can simply click 'Send out' which will then again call WCF service to send the emails.
Because at times it can take a bit longer for emails object processingy, I do not want calling application to wait until emails object is ready.
Can anyone please guide what changes I need to make to my WCF service (which currently has all one way operation)?
Also, please guide me whether I need to go for Asynch operation or message queuing or may be a duplex contract?
Thank you!
Based on your description I think you will have to:
Change current operation from sending email to storing email (probably in database).
Add additional operation for retrieving prepared emails for current user
Add additional method to confirm sending one or more emails and removing them from storage.
The process will be:
User will trigger some http request which will result in calling your WCF service for processing (first operation)
WCF service will initiate some processing (asynchronously or firt operation will be one-way so that client doesn't have to wait).
Processing will save email somehow
Depend on duration of processing you can either use AJAX to poll WebApp which will in turn poll WCF service for prepared emails or you will create separate page which will user have to access to see prepared emails. Both methods are using second operation.
User will check prepared email(s) and trigger http request which will result in calling third operation to send those emails.
You have multiple options:
Use Ladislav's approach. Only to add that service returns a token and then client uses the token to poll until a time out or a successful response. Also server keeps these temp emails for a while and after a timeout purges them.
Use duplex communication so that server also gets a way to callback the client and does so when it has finished processing. But don't do this - and here is my view why not.
Use an Asynchronous approach. You can find nice info here.