Access SOAP webservice with ServiceStack - web-services

I'm creating my client/server application intercommunication with ServiceStack, and is working great, but I need also to access an external SOAP web service.
I tried to use the Soap12ServiceClient to access it, but I couldn't find any example, and then I went the add service reference WCF way that actually worked, but creating a ton of code.
Is it possible to use Soap12ServiceClient in the same easy way I use JsonServiceClient to send a message/request and receive the message/response? If so, can you help or point me to a sample?

I'm not sure where you're stuck as all of ServiceStack's C# Service Clients implement the same IServiceClient so they can be used in the same way. Here is an example of all of ServiceStack's built-in C# Service Clients calling the same Hello World service:
[TestFixture]
public class HelloWorldServiceClientTests
{
public static IEnumerable ServiceClients
{
get
{
return new IServiceClient[] {
new JsonServiceClient(Config.ServiceStackBaseUri),
new JsvServiceClient(Config.ServiceStackBaseUri),
new XmlServiceClient(Config.ServiceStackBaseUri),
new Soap11ServiceClient(Config.ServiceStackBaseUri),
new Soap12ServiceClient(Config.ServiceStackBaseUri)
};
}
}
[Test, TestCaseSource("ServiceClients")]
public void HelloWorld_with_Sync_ServiceClients(IServiceClient client)
{
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
Assert.That(response.Result, Is.EqualTo("Hello, World!"));
}
}
Although SOAP works similar to any other C# client, it's un-common to use it in this way because if you're able to use a generic C# SOAP service client you're also likely able to use any of the other service clients which are all faster, more resilient and more versionable than SOAP - which has effectively has no redeeming quality over the other formats other than its ability to generate client proxies which you said you don't want to do anyway.
If you're undecided which endpoint or format you should use I recommend reading my Interview on InfoQ which discusses the disadvantages of SOAP and the benefits of using the other formats.

Related

How to build request handler class in lambda function for a Springboot CRUD Application?

I am trying to invoke a lambda function by the new feature - function URL"S https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html using which I don't require any trigger events.
I am able to get the output for a simple java application using the above approach written in documentation by using Java as runtimeEnvironment and passing Jar file from my local machine.
Now, I want to test lambda functionality by same concept but for Springboot-Application which has restful endpoints for GET,POST,PUT,DELETE for different crud operations connecting with MySql db. The problem I am facing is how to tell handler class that to route to these endpoints and trigger lambda functions.
Any help/suggestions appreciated here. Thanks in Advance !
It probably won't work with this URL's feature but it allows handling Lambda events similar to standard Spring web requests.
You can check this one: https://github.com/MelonProjectCom/lambda-http-router
Example usage:
#PathPostMapping("/example/test")
public String example(#Body String body) {
return "Hello World! - body: " + body;
}

Truncated Java object when passing through JAX-WS WebService

I am currently working on a project that uses JAX-WS webservices in Java.
The global topic is this : the user creates locally an object, let's say an Agent. He calls a first webservice and passes its Agent to the webservice. The webservice treats the Agent (modifies its properties : e.g. lifepoints), and passes it to another webservice. This call is made from the first webservice, so the user has nothing to do in the process.
After a chain of several webservices, the user retrieves the Agent that has been modified.
The aim of my project is to design 2 parts:
a framework that specifies the behaviour previously described : webservices, Agents and the process of migration
a demo application using my framework. The main difference is the addition of a GUI and a new class Avatar, that extends Agent. So the migration process is still being done "by the framework", with Agent objects.
The following code shows a simple example of how I call my webservice, host my Avatar, then retrieves the agent from the service :
// connection to the server
URL endpoint= new URL("http://SERVER/tomcat/KiwiBidonDynamique/ServiceWebBidonDeDadou?wsdl");
QName serviceName=new QName("http://avatar/","ServeurKiwiBidonService");
Service service = Service.create(endpoint, serviceName);
WebService port = service.getPort(WebService.class);
Avatar myAvatar = new Avatar(1, "Jack the Ripper");
port.hostAgent(myAvatar);
// some process on the service...
Avatar myAvatarTransformed = (Avatar) port.getAgent("AgentNumberOne");
When I do that, I get an exception on the final line :
Exception in thread "main" java.lang.ClassCastException: agent.Agent cannot be cast to avatar.Avatar
After a lot of log reading, I guess the reason is the way the webservice works. When being called, my Avatar given in parameter is marshalled in my JVM then unmarshalled on the service, but the service only constructs an Agent when it unmarshalles. Doing so, it truncates the data specific to the Avatar. Then when I try to retrieve my Agent from the service, it cannot be cast to an Avatar.
Is there a way to keep the Avatar information while processing as an Agent on the service ?
Can I write my own marshalling/unmarshalling somehow ?
Thanks a lot.
If your webservice has Agent element defined as incoming data, then no it is not possible to unmarshall it into an inherited class. I guess it would be possible to write your own marshaller but it is not as easy as it sounds (I would advise against it). Either write a separate WS for each class (messy) or make the incoming data have an element that can store additional structures, like type:any (also messy). The truth is WS are not exactly OO.

How to connect ActiveMQ to CXF with Apache Camel

does anyone know a working example that bridges ActiveMQ to CXF? I saw many examples that connect a WebService to a message queue, but I need it the other way round. Messages from a JMS queue shall be forwarded to a web service and the result returned to the caller.
My first approach is only working for web services that expose one single method:
from("activemq:wsa").to("cxf:bean:webServiceA");
Status msg = producerTemplate.requestBody("activemq:wsa", params, Status.class);
But for web services that have more than one method, a similar call results in a ExchangeTimedOutException.
Map<String, Object> header = new HashMap<String, Object>();
header.put(CxfConstants.OPERATION_NAME, "doSomething");
header.put(CxfConstants.OPERATION_NAMESPACE, "http://.../");
Status msg = producerTemplate.requestBodyAndHeaders("activemq:wsb", params, header, Status.class);
Nevertheless, I can see that the request is forward to the web service and the correct answer is returned. But unfortunately then it gets lost on its way back.
Any hints or links to external resources are appreciated.
Many regards,
Jakob
ActiveMQ and JMS calls are one way default, you may want to specify it to be synchronous.
http://camel.apache.org/jms.html#JMS-RequestreplyoverJMS
Other than that, it should be no different to use ActiveMQ as a starter for CXF producers.
A suggestion is to download the Camel source and look into this folder:
\components\camel-cxf\src\test\java\org\apache\camel\component\cxf
(or by Web: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/)
You will have a huge amount of CXF producer test cases, to look at as reference material.
The problem occurs when a web service returns objects of classes that don't implement the serializable interface, even if these classes are serializable.
Implementing the serializable interface solves the problem.

Spring MessageListener multiple Messages

I am implementing a Spring MessageListener that is listening to a JMS Queue to process messages containing XML.
My bean ProposalSOAListener will be processing about 5 or more XML messages from the queue. My code is below.
Is there a way to specify different methods on this class to handle different XML messages?
public class ProposalSOAListener implements MessageListener {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
System.out.println(((TextMessage) message).getText());
} catch (JMSException ex) {
throw new RuntimeException(ex);
}
}
else {
throw new IllegalArgumentException("Message must be of type TextMessage");
}
}
} // end of ProposalSOAListener class
There's a bunch of architectural questions begged by your question. Do you want this mesasge listener to do the work, or hand it off to another component? Are there transactional considerations at play? Do you have memory constraints - i.e. do you want streaming based XML processing or not? Do
The good news is that you have a lot of the pieces to this puzzle available to you within Spring.
A simple next step would be to use Spring Object XML Marshalling (OXM), choose one of the techniques, and wire the marshaller into your listener bean.
See http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/oxm.html
Another technique would be to use the Spring ApplicationEvent interface, read the messages coming in off the queue and publish them internally to listeners of the specific types. That could be used in combination with the above object marshalling.
Last but not least, if this is SOAP web services - you can take a look at Spring WS, it uses the similar message containers to pull messages off the wire, marshall them, and invoke a spring ws endpoint (ie. the service interface that satisfies that interface contract).
http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d4e907
Spring Integration project is highly recommended for this kind of a problem. Essentially you will have to implement a jms inbound gateway to get your message in. You can then transform this to an object at this point, then route the message to the appropriate service-activator component, which can map to your instance and method.

Consuming services that consume other services

What is the best way to confirm that these consumed services are actually up and running before I actually try to invoke its operation contracts? I want to do this so that I can gracefully display some message to the customer to give him/her a more pleasant user experience. Thanks.
I created an IsAvailable method that checked all of my underlying dependencies for my service. My client would call this method before doing anything else with my service. If it returned true, my service was available for use.
We also put intermediaten checks to rollback any changes if one of the underlying dependencies was not able at the time of the transaction.
Example:
Here is a simple example of how my IsAvailable is used by the client:
IsAvailable code
[WebMethod]
public bool IsAvailable()
{
bool EverythingUpAndRunning = true;
try
{
string TestConnectionString = WebConfigurationManager.ConnectionStrings["Sql"].ConnectionString;
SqlConnection sqlConnection = new SqlConnection(TestConnectionString);
sqlConnection.Open();
sqlConnection.Close();
sqlConnection.Dispose();
}
catch(Exception ex)
{
EverythingUpAndRunning = false;
}
return EverythingUpAndRunning;
}
The client code:
MyWebService proxy = new MyWebService();
if(proxy.IsAvailable)
{
//if true, you can use the other available methods in the service
}
I wouldn't consider myself a part of the SO Community but I have been in this situation before and it was simple exception handling around the service calls. If you're in control of the services, than you can put up a status method that returns it's current state. If the network is down and you can't even hit the service than you'll have to handle that with some exception handling but you could get a status back if the parent service is unable to use it's child services.
If you're following SO though, my own opinion here, you shouldn't be concerned with the consumed service consuming other services.