How to define contract for both messaging and http API using sping-contract - spring-cloud

I have a situation where there are 2 services. Service A is exposing query API through HTTP endpoint and also is listening for incomming asynchronous command messages (service A owns both of CQRS contracts).
Service B is using both endpoints of service A: to GET data and to invoke commands.
While implementing contract (stub and tests) for HTTP flow is quite simple, configuring messaging part is a tricky for me and actually I've stucked at this one.
Docs says that there is publisher side test generation what is suitable for publishing event case where publisher owns the contract.
But how to makes it working for situation where message consumer owns the contract??
I can't figure out any solution on that one as I need to have a stub used in service A to verify if service A is properly consuming commands messages and also I need genereated tests on service B that will verify that service B if it is producing compliant command message.
I'd appreciate any help.
Many thanks in advance.

Service A is the producer of the API and the consumer of messages. It owns only contracts for HTTP. The messaging contracts are owned by Service B. Service B is the producer of messages. You should have an HTTP contract defined on the Service A side and a Stub Runner test to test if it can receive the message sent by Service B. Service B should have the messaging contract to assert whether the message is properly sent and Stub Runner test for HTTP
That might lead to a dependency cycle. If you have a cycle between your apps then, yeah, what you have to do is ignore a stub runner test on one side until the jars got uploaded.
You've asked about storing contracts in a separate repository. You can do it - here are the docs https://cloud.spring.io/spring-cloud-static/Edgware.SR3/multi/multi__spring_cloud_contract_faq.html#_common_repo_with_contracts and here is an example https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/beer_contracts
You've asked about not generating the tests for some reason (IMO that's a wrong thing to do). You can not use <extensions>true</extensions> in Maven but manually provide which goals you want to execute (omit the test generation). In Gradle just disable generateContractTests task AFAIR

Related

Create Service broker for Play Framework Api

I have created a sample play framework api which has one endpoint.
http://play-demo-broker.cfapps.io/say?number=20
Which just return me number that have passed.
I am able successfully deploy the service. Next want this service to Act like service broker
For same want to register this as by using below command
cf create-service-broker play-demo-broker admin admin http://play-demo-broker.cfapps.io --space-scoped
This command it giving me below error -
The service broker rejected the request. Status Code: 404 Not Found
Not sure what is causing this issue as there not much information available for Play Framework Service broker Setup.
The play framework is implemented above the akka packages. Akka rejects paths that are not implemented.
If I an not mistaken, cf create-service-broker command access the / endpoint. If you implemented only say?number=20 endpoint, then be default all other paths, such as the empty path, are rejected by Akka.
In order to open that endpoint you need to add it into the routes.
For example you can add:
GET / controllers.ControllerName.GetEmptyPath
And implement the GetEmptyPath method in ControllerName

RestTemplate annotated by #LoadBalanced get wrong service address by service name from eureka sometimes

I use springcloud to build the system, including many microservices。 For some interface calls, I use resttemplate annotated by #LoadBalance to implement load balancing, and use eureka as a registry center. However, when I call interfaces between different micro services, resttemplate sometimes will connect to wrong service. For example, I have service A, B, C, when service A call a service B's interface, resttemplate annotated by #LoadBalance will find the actual ip&port from eureka by service name first, and then build the actual url and send the request to target server, but sometimes, it will find the service C's ip&port when I call service B's interface, which cause a fail invoking. This case occurs infrequently but nerver disappear, I have been troubled for a long time, could anyone give me some suggestions? Thanks.
I learned why yesterday: it is a bug in spring cloud Dalston.RELEASE(https://github.com/spring-cloud/spring-cloud-commons/issues/224), and we happen to use this version. Spring cloud had fixed this bug in Dalston.SR2, and now it works fine

NServiceBus disposing Autofac Container

Here goes - bear with me:
Two Autofac 4.2.1 Containers:
One in an Asp.NET 4.6.1 WebApi project
One in an NServiceBus 6 host
Both possess an IJobService reference to the JobService (which saves jobs to DynamoDB).
Run the project in Visual Studio...
If I make a WebApi request into the first JobService it succeeds and inserts a record to DynamoDB and drops a command on the bus for NServiceBus to pickup.
During the processing of the Saga, NServiceBus makes a call to JobService again (presumably on the second container) to save progress. This second call fails to insert to DynamoDB with the lifetime disposed. If I try to create anything from IComponentContext I get:
Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed.
The NServiceBus host is running AsA_Server and I register the container in the Customize method of IConfigureThisEndPoint.
Any pointers on how to see where the lifetime is getting dumped or if it's mysteriously picking the wrong IJobService somehow?
Just to close this one out - we ended up redesigning the solution and moving any web service calls out to their own handlers. That was based off the advice found here http://docs.particular.net/nservicebus/sagas That change resolved the issue one way or another.
Specifically, this guidance:
Other than interacting with its own internal state, a saga should not access a database, call out to web services, or access other resources - neither directly nor indirectly by having such dependencies injected into it.

JBoss Fuse v6.2 - Tracing

What is the way to do message tracing for each request made to the JBoss Fuse 6.2 server? In my case most of the entry points are CXF REST service with the processing delegated to Camel routes in some cases. I would like to do end-to-end tracing with same message id that can correlate the request processing.
In my project, there was a similar requirement. Customer wanted to see all e2e log by executing grep command to system logs with a transaction id.
I used CXF interceptors and MDC logging capability for this as below:
Create a common CXF request and response interceptors. Add them to all your Camel's CXF Server/Client configuration
With your request interceptor, extract transaction id from request (or generte it yourself) then put it into MDC map. MDC is a thread local variable that log4j, slf4j,.. uses.
Print request, it'll have your transaction id as prefix thanks to MDC.
Dont forget to add your MDC key in logging format configuration
All logs you print until the end of operation with this transaction Id until the end.
If you're always using direct-vm, direct for routing then it wont be problem. However as you may know using seda, multi processing, etc. your execution is handled by other threads. Since MDC is thread local variable, you need to manually handle the trouble by transferring it.
With your response interceptor, log response message then clear MDC values.
If you're using CXF as client, you should use same interceptor approach to be able to print client request/reponses with transaction id.
See CXF-RS and MDC links as entry points

Websphere Message Broker SOAP Request Node calling .NET web service in gateway mode (no WSDL)

I have been struggling with this issue for a while now and all of the search results (and there are many that I have read) do not seem to apply to my situation.
I have a Websphere Message Broker message flow with a subflow that is calling a web service that was written in Visual Studio. I am trying to call this web service in Gateway Mode which means that I do not have the WSDL to plug into in the properties of the SOAP Request Node in the Broker Toolkit I am using to write this flow.
The error message I am getting is a common one:
The message with Action SendEmail cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
I am unsure how to proceed with this. Because of the Gateway mode, many of the properties are not configurable in the properties of the SOAP Request Node. Can I set these in the ESQL code, perhaps in the message someplace such as the HTTPRequestHeader?
I am using Websphere 8, Broker Toolkit 7.5. Transport for the message is HTTP and SSL is not used. WS-Addressing is also not being used.
Any suggestions would be most welcome.
Yes, in gateway mode you do not need a WSDL. Your target web service required additional info like below.
le.getRootElement().evaluateXPath("?Destination/?SOAP/?Request/?WSA/?Action[set-value('"+Action+"')]");
Try setting your local environment destination as above. The action can be set according to the WSDL file you have gotten.
How to search for action: First use the provider url:
http://URL?WSDL
After that search for the action word. you can see request action like below.
<input wsam:Action="http//ActionURL.bla.bla.bla" message="tns:blabla" />
So just SET Action = 'http//ActionURL.bla.bla.bla'