I need to create the dynamic client to call web services, which can call web services with Service Mode as Service.Mode.PAYLOAD as well as Service.Mode.MESSAGE. I have created the Dispatcher as:
Dispatch<Source> sourceDispatch =service.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);
But this can invoke the services with Service Mode PAYLOAD only. Please suggest me the way how can I previously determine the Service Mode from WSDL link (service Mode parser code) before creating Dispatch instance?
The mode does not depend on the WSDL.
If you want to pass to sourceDispatch.invoke(T msg) an entire SOAP message use mode.MESSAGE. If you only want to pass the PAYLOAD (the body) use mode.PAYLOAD, and invoke will wrap it in a message for you.
The mode also determines wether invoke returns you a message or the payload.
Related
We struggle to find a solution for the following scenario:
Situation
Receive a message via Spring Cloud Streamlistener
Invoke a REST-Service via Feign-Client
We have configured several Feign-RequestInterceptor to enrich
request header data.
We want to avoid passing every request header on the method call and like the central configuration approach of the request interceptors.
Problem:
How to access data from a specific message, which contains informations, that need to be added to every request call via the Feign-RequestInterceptor.
We don't have a Request-Context, as we come from a message.
Can we be sure , that the message consumption and the REST call is happening on the same thread? If yes, we could use the NamedThreadLocal to store the information.
Yes, unless you hand off to another thread in your StreamListener, the rest call will be made on the same thread (assuming you are using RestTemplate and not the reactive web client).
I'm developing several services on Java that communicate with each other through HTTP. Logback is used as logging framework.
In case of error within one service it's not difficult to define error reason looking through the service logs. But if we have a downstream call that affects a number of services:
Service A -> Service B -> Service C -> Service D
and the last service failed with an error, I need some means to trace the call up to Service A to troubleshoot the issue.
Are there any ready solutions for the problem? Should I add some additional attribute to log message that is unique for each downstream call?
If you want to trace the flow of execution you need some sort of tag on each message. You will need:
a request identifier
a service identifier.
When a flow is started you tag the first call with the request identifier and the service identifier. On each service that handles the call and needs to make other calls, to other services, you keep the request identifier and add the current service identifier to the one of the request you received.
Basically the request identifier allows you to identify a flow of calls, while the service identifiers allow you to see the hops in the flow.
For your example, Service A -> Service B -> Service C -> Service D, you might have something like this:
Service A starts a call "123-A";
service B receives this and needs to make a call to service C, so it uses "123-A" and ads his identifier: "123-A,B";
service C receives this and needs to make a call to service D, so it uses "123-A,B" and ads his identifier: "123-A,B,C";
if something happens with the request in service D, you know on what service logs to look (A,B,C) and what to look for (123).
You can have these in the HTTP message or as HTTP headers, the idea is to somehow add them to the log message whenever you log something.
Of course the above is for a simple case as the one you gave an example of, so it can be extended for other cases. The idea is to treat the calls as a sort of stack. On each hop you "push" some identification into the message.
There is actually a solution for spring-based services: request correlation spring cloud starter.
The filter adds unique request identifier as a header (if there is no such header) to each request. One can put the id to MDC and add it to log entries with service id.
I am using following approaches to create web service client. I could likte to know if connection between client and server is established after creating stub instance like followings.
Otherwise Is connection between client and server established after invoking Remote method calling such as stub.xxxmethod(), myervicePort.xxxMetho()
RPC/Encoded
stub = new MyWsRPCPortStub(new URL(), new MyWsRPCLocator());
stub.setTimeout(pdbTimeout);
Document/Literal
MyServicePort myervicePort = service.getMyServicePort();
After learning the above question I am going to decide when stub instance will be created? I mean there will be two ways:
1- create only one stub instance in application ,I mean I will use singleton pattern
2- create stub instance before invoking a method call each time
What if I use only one stub instance with multithread appiication, each thread open difference sockets at the same time while invoking stub.xxMethod()
At the same time
T1->stub.xxMethod()
T2->stub.xxMethod()
T3->stub.xxMethod()
First of all the approcahes you have mentioned to consume web service in a client do not depend on wether the web service style is RPC or Document Literal. The client is the same for both styles. These styles merely determine how the SOAP message exchanged between client and server is structured. A post to get started on it:-
here.
Messages are sent between the client and server using the SOAP protocol running over HTTP. Hence the communication between client and server should be mainly looked at as a normal HTTP request/response model rather than when and how the connection between them is established and maintained which is the job of underlying TCP protocol; and the API in the web service client and the underlying OS completely abstract away these details for us.
However if you would like to know when a HTTP request is made by a web service client; you can trace it using any of the packet capture tools like 'wireshark' for example.Typically if you have a web service with just one method; there is usually a HTTP GET request made when you use the Service service = Service.create(url, qname) api and a HTTP POST on YourWSInterface.xxxmethod().
About when to create a stub; in a multithreaded environment; if you are going to use the BindingProvider on the client stubs to set data(and not just mere read only calls) before sending to the webservice; yes; you would need some syhcnronization in the client code(with a single instance) or create a pool of client proxies(multiple pooled instances); depending on the requirements of your app.
I hope i have answered the question.
I am new to webservices. I know wsdl is used to generate consumer side stubs to send the request to producer.
My question is does producer also uses the WSDL file in any way to map the the incoming message to sorresponding
service implementation class ?
May be producer does not use the WSDL instead skelton is created when service is published and prodeucer use this
sketon to map the incoming request to right service implemtation?
Absolutely right..
Producer generate the wsdl and store it somewhere so that it can be provided to consumer to understand the request and response message structure along with the protocol, operations and service location.
Webservice implementation frameworks like cxf etc. already know How they are going to receive message from consumer, which operation they are going to call. They simply marshal and unmarshal incoming request and outgoing response. They don't use wsdl.
In my opinion.
Correct me experts if i am wrong...
Context :
SAP Solution Manager (will call it SolMan) exposes a SOAP webservice where a 3rd party can call to interoperate with it. The 3rd party application can also implement the same webservice interface so that SolMan can interoperate in the other direction.
I need to interoperate with SolMan in both directions. My webservice is a WCF Service based on the interface and the types generated from the WSDL of the SolMan webservice with VS2010 "Add Service reference".
Problem #1
In the WSDL, all of the declared operations has soapAction="". When the service contract interface has been generated from VS2010, all OperationContractAttribute are Action="", ReplyAction="*". Since more than one OperationContract has the same Action (empty string), the Webservice doesn't work, the exception is :
[InvalidOperationException: The operations AcceptIncidentProcessing
and AddInfo have the same action (). Every operation must have a
unique action value.]
Is this normal? There is another way to fix it other than removing all Action="" declarations from the generated ServiceContract interface?
Problem #2
I've removed all empty string Actions from the generated ServiceContract interface.
I can now inspect the WSDL generated by my webservice and call it with my .net wcf client.
SolMan is unable to call my webservice, after enabling MessageLogging in my web.config, I found that my service has faulted with :
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none" xmlns="">a:ActionNotSupported</faultcode>
<faultstring xml:lang="en-CA" xmlns="">The message with Action '' 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).</faultstring>
</s:Fault>
Indeed inspecting the SOAP request message shows that soapaction is present in the HTTP Headers, but empty, and that Action is also presents in the SOAP headers and it is also empty .
So I found a Post about the Microsoft's 1DispatchByBodyBehavior1 sample, gave it a try and replayed the http request with Fiddler wihout success. The only way I manage to make it work, is by removing the <Action> and <To> from the SOAP headers in Fiddler. SolMan will indeed continue to pass these headers.
Is it valid that SolMan sets no Action when calling a SOAP webservice?
What am I doing wrong?