Making a reliable web service unreliable, but in a controlled way? - java

I have a Java 6 based web service client using the standard Java 6 annotation based approach (i.e. no Axis or other third party web service library), which works very well. So does the web service I am calling, which is nice, but now I need to write error handling code, and I need to be able to make the existing web service unreliable in a controlled way.
There are many mock frameworks, and they may be helpful, but I don't need right now to be able to mock out the service with prerecorded answers or anything, just introduce unreliability causing the web service library to fail so I can handle the situation gracefully. This would probably be a proxy server running locally.
I work with Eclipse Java EE 3.6, but Netbeans, IntelliJ and JDeveloper are also options.
What would be the best way to do this?

Tcpmon, http://ws.apache.org/commons/tcpmon/index.html can be set up to act as a proxy and even simulate slow connections.
That would give you a chance to simulate both "sorry, not here" and "yes, we are here but we time out".

Any introduced instability is likely to lead to operation avenues of instability being missed. Aim to cover all potential error vectors in your code rather than trying to mitigate for specifics.

Since You've not disclosed enough details of your setup, maybe throwing Exception here and there would be enough?
Seriously, for integration tests like this I'd suggest running some subset of a real web service container.
Based on service's logic it may behave unreliably because of:
external system it is using is misbehaving - try to mock the external system and throw faults - different types - from it
database access problem - try mocking DAO layer and throw Exception from there
general hardware problem - depends :) try to stress your code as you see fit

I think rather than introducing unreliability to a running-instance of the web service application, you are better off simulating error conditions in your unit/integration tests and asserting that your top-layer of the service responds the way that you would like.
For example:
How does the service entry-point respond to a request if the data layer reports that it cannot communicate with the backend (if the data layer throws exceptions, or however it indicates failure)
How does the service entry-point behave if other required components are throwing "unavailable"-like exceptions?
Do you have any timeout logic in place, i.e. the service returns an error if it takes more than X seconds to process the request? If so, this can be simulated in a mock test as well.

Related

How do I use a Spring MVC Controller as a Fake Endpoint for an Integration Test?

I have a service that calls out to a third-party endpoint using java.net.URLConnection. As part of an integration test that uses this service I would like to use a fake endpoint of my own construction.
I have made a Spring MVC Controller that simulates that behaviour of the endpoint I require. (I know this endpoint works as expected as I included it in my web app's servlet config and hit it from a browser once started).
I am having trouble figuring out how I can get this fake endpoint available for my integration test.
Is there some feature of Spring-Test that would help me here?
Do I somehow need to start up a servlet at the beginning of my test?
Are there any other solutions entirely?
It's a bad idea to use a Spring MVC controller as a fake endpoint. There is no way to simply have the controller available for the integration test and starting a servlet with just that controller alongside whatever you are testing requires a lot of configuration.
It is much better to use a mocking framework like MockServer (http://www.mock-server.com/) to create your fake endpoint. MockServer should be powerful enough to cover even complex responses from the fake endpoint, with relatively little setup.
Check out Spring MVC Test that was added to Spring in version 3.2.
Here are some tutorials: 1, 2, 3
First I think we should get the terminology right. There are two general groups of "fake" objects in testing (simplified): a mock, which returns predefined answers on predefined input and stubs which are a simplified version of the object the SUT (system under test) communicates with. While a mock basically does nothing than to provide a response, a stub might use a live algorithm, but not store it's results in a database or send them to customers via eMail for example. I am no expert in testing, but those two fake objects are rather to be used in unit and depending on their scope in acceptance tests.
So your sut communicates with a remote system during integration test. In my book this is the perfect time to actually test how your software integrates with other systems, so your software should be tested against a test version of the remote system. In case this is not possible (they might not have a test system) you are conceptually in some sort of trouble. You can shape your stub or mock only in a way you expect it to work, very much like the part of the software you have written to communicate with that remote service. This leaves out some important things you want to test with integration tests: Was the client side implemented correctly so that it will work with the live server. Do we have to develop work around as there are implementation errors on the server side? In which scale will the communication with the remote system affect our software's performance? Do our authentication credentials work? Does the authentication mechanism work? What are the technical and conceptual implications of this communication relationship no one has thought of so far? (Believe me, the latter will happen more often than you might expect!)
Generally speaking: What will happen if you do integration tests against a mock or a stub is that you test against your own understanding of how to implement the client and the server side of communication, and you do not test how your client works with the actual remote server or at least the best thing next to that, a test system. I can tell you from experience: never make assumptions on how a remote system should behave - test it. Even when talking of a JMS server: test it!
In case you are working for a company, testing against a provided test system is even more important: if you software works against a test system and you can prove it (selenium is a good helper here, as well as good logging, believe it or not) and your software does not work with a live version, you have a situation which I call "instablame": it is immediately obvious that it is not your fault the software isn't working. I myself hate fingerpointing to the bone, but most suits tend to ask "Who's fault was it?" even before "Can we fix that immediately?" and way before "How can we solve that problem?". And there is a special group of suits called lawyers, you know ... ;)
That being said: if you absolutely have to use those stubs during your integration tests, I would create an own project for them (let's say "MyProject-IT-Stubs" and build and run the latest version of MyProject-IT-Stubs before I run the IT of my main project. When using maven, you could create MyProject-IT-Stubs with war packaging, call it as a dependency during the pre-integration-test phase and fire up a jetty for this war in the same phase. Then your integration tests run, either successful or not and you can tear down the jetty in the post-integration-test phase.
The IMHO best way to organize your project with maven would be to have a project with three modules: MyProject,MyProject-IT-Stubs and MyProject-IT(declaring dependencies on MyProject and MyProject-IT-Stubs. This keeps your projects nice and tidy and the stubs do not pollute your project. You might want to think about organizing MyProject-IT-Stubs into modules as well, one for each remote system you have to talk to. As soon as you have test access, you can simply deactivate the according module in MyProject-IT-Stubs.
I am sure according options exist for InsertYourBuildToolHere.

Restful Webservices using Java, Apache Axis2, Hibernate and MySQL and its performance

I read somewhere use of webservcies in apps. After a lot of research I am able to create one Webservice which will accept Json and JsonP both format as request and response accordingly. I developed the webservcies using Java, Apache Axis2, Hibernate and MySQL as database. there are few problems and I dont know how to solve ?
Insert or delete option, sometimes if at a time more than two users call that service that is insert or delete any row the queries go in sleep mode and next time someone tries to fetch that service he couldnt. Accroding to server log it says error SQL Lockout State. If I checks Processlist in MYSQL it is showing that query in Sleep, I have to kill to resume.
The performance of webservice doesnt seems to be upto mark, it takes time some more time as what i experienced it shouldn't. In simple words how to obtain better performance by the services
How to implement security feature such that if a user logins he/she can be provided an id and validation of that id so that unauthorized access can be prevented
Or just guide me what should be the most appropriate and optmized Webservice methodology that can be used using Java
Answer to this question is not specific to Android. Below are my investigations which might be useful for you.
For the point about MySQL connections going to sleep mode, you can do the following.
Debug the datasource used by Hibernate, try to increase the pool size & check for any issues in it.
Define a timeout period for connections. JBoss has several configurations related to this like blocking-timeout-millis, idle-timeout-minutes etc.
Declare a mechanism to validate periodically the connection resources in the pool for activeness. You can explore OracleStaleConnectionChecker for options.
Configure miniumn connections in the pool. This is important because when all the stale connections are discarded, empty pool needs to be pre-filled & ready with active connections.
Coming to performance of Insert/Delete operations & SQL Lockout State, please try to re-order the sequence of the queries which you are firing to DB at every request. This may not be a deadlock situation but sequencing DB queries correctly will definitely lead to less lockout time and better performance.
This answer may be of use for you. Hibernate: Deadlock found when trying to obtain lock
Web-services which you have developed may require some performance optimization to make them upto the mark. Below are first few steps you can take to bring the performance up.
Avoid nested loops. Every extra parameter in the iterated lust increase the order of the lopp exponentially.
Remove early initialization of objects. This may lead to long unwanted GC cycles.
Apart from above optimizations, there are several frameworks & tools at your service to evaluate the code quality & its performance. PMD, FindBugs, JMeter, Java profiler are few of them to name.
Shishir
You are going to have to profile your server and see where the time is spent. I really like YourKit for doing thread profile. visualvm which comes with the JDK can help also.
There are all sorts of reasons your web service can be slow:
Latency from client to server
Handling the HTTP request on the server
Handling the HTTP response on the client
Making the database call (sounds like you already have some kind of locking / blocking going on there)
You are going to have to get markers to tell you how long it took to go from A to B to C to D back to C back to B back to A kind of thing. We would be speculating heavily from here on what is exactly going on in your program, but we can give you the ideas / tools to figure it out.
If you use YourKit, connect it to your server process. Have nothing else connecting to your server (for instance your client is not sending requests). Try it with your client requesting, you should see your accepting threads receive the HTTP request and then delegate to either your processing thread or do the processing itself. You can use YourKit to see how much time is spent in different functions during that call time.
Try it with your client making the call.
Try it using a simple HTTP request tool like wget or maybe your IDE has a webservice test tool (for instance intellij does), or you can download a simple HTTP test tool.
By testing it in a simple tool that just outputs the response, you can eliminate any client processing issues. You can also achieve a similar test in Chrome or Firefox and use the developer tools to see time to fulfill request.
In my experience, the framework for handling the requests and delegating can introduce some performance issues. I ripped Grails out of a production environment because of its performance issues (before any Grails / Groovy flames come my way, we were operating at a much higher rate than typical web applications, and I am sure Grails has made some headway in the last couple years... alas, it was not for my need at that time)
BTW, I doubt you are operating a load where you will be critiquing the web service framework you chose to use. I have been happy with Spring MVC and DropWizard (Jersey JAX-RS), and Grails is easy to use too.
You should make a simple static content response in your webservice and see how quickly that returns vs a request that makes a database call.
Also, what kind of table are you using in MySQL? InnoDB? MyISAM? They have different locking schemes. That could be causing your MySQL issue.
The key to all of it, break the problem up into parts, and measure each and eliminate parts one by one till you go, everytime I do X it is slower (like everytime I make a database call its slower)
In Java the the way you will be able to find more support online via documentation/forums is to develop the web service as a REST web service using Spring MVC.
You can base yourself on this resource and take it from there:
Spring MVC REST Hello World Web Service
Using Spring you can create a RestFul webservice easily and spring does all the ground work you needed. As others had mentioned you can consume the webservice in any type of client - including Android.
A detailed guide available here:
https://spring.io/guides/gs/rest-service/
Here are my suggestions:
Make APIs only read or write database. If an API combines reading and writing, it is possible to cause deadlock;
Use a light-weight HTTP server. Powerful HTTP server is possibly consuming more.
Make use of thread. Have more threads could be helpful when you are facing a ton of users.
Make more things static. You could avoid unnecessary queries.
I think mhoglan's answer is detailed enough.

Simulate slow HTTP connect for Java integration test?

is it possible to simulate a slow HTTP connect in a Java integration test, so that I can define how long the server should wait until he confirms the connection? A solution which also supports a JAX-WS webservice would be perfect.
Background:
I have to integration test a central timeout configurator. The configurator itself must be technology-independent. At first it supports JAX-WS webservices, therefore the attribute com.sun.xml.ws.connect.timeout will be set in request context.
(I'll try to convince them, that it is part of JAX-WS and thus we don't need to test it, but this question is my backup plan.)
P.S.: There are other questions which ask about simulating a slow connection in general. This is different because I cannot use external tools in an unit test and I must be able to define a specific connection time.
In one of my unit test, I used NanoHTTPd https://github.com/NanoHttpd/nanohttpd which is a pure Java. It is only one class.
You can go through a proxy (http or socks) which can be embedded in your application. You can then tell the proxy to provide the behavior you need to test.
I had to test a dropped TCP/IP connection (How to reproduce a silently dropped TCP/IP connection?) and ended up going through a SOCKS proxy written in Java, which I just suspended to emulate the behavior I was looking for.

Creating a Java server which is restarted automatically on failures

I am creating a Java service which will run within a web servlet container (probably Tomcat). One portion of the server will run on its own and will not be initiated by HTTP. I know that when an HTTP call causes an exception, the web container can call it again.
I want to be sure that the part of the server which runs continuously will continue to run, even if it fails. I will handle whichever failures I can manually, but if it all fails I want something to restart it all. Are there any tools that can accomplish this easily? I am already using Spring and Tomcat, so if those can provide it, that is ideal. If not, then how about a good design pattern?
Edit: To clarify, I have a web service which will run in Tomcat. I want to run a separate thread within that service and set it up such that when the thread ends or an un-handled exception occurs, Tomcat (or something else) detects the failure and restarts the web service. I know that typically web containers have threads start from some external call and thus handle failures from those threads. What I want is something which handles a background worker thread.
Not quite clear on the design you have in mind, but it seems to me you need some sort of health check.
You can implement such a mechanism in many ways e.g. open a socket from this process that runs all time and periodically send a message.
If there is no reply then the process failed.
You could restart tomcat or implement a mechanism to restart that process.
Can not tell you more details since you do not specify much on what you are trying to do.
UPDATE:
I think that you should use JMX. It is offered by Spring and Tomcat that you already use.
Just make the process you want to monitor a managed resource and another module can check if it is alive.
If you are running inside a Servlet then as per J2EE spec, you cannot restart the container but, you can use ScheduledExecutorService to continuously monitor that your service is running and if not, then re-start it.
EDIT. More details below
You can call isTerminated() to check if the service still running and add more tasks to it, if the queue is empty.
I may be misunderstanding your problem here, but you might be over-thinking it.
There's nothing stopping you from running multiple Tomcat instances on a single machine. You could then have Server A connect to Server B to pull down information (via a web service of your choosing). This would alleviate the need for an outage on server A to cause an outage on server B (which is what I'm assuming you're trying to avoid).
This is a common way to isolate production environments simply by binding to a separate port. If Tomcat doesn't fit the bill for the service you can always run the application as a service on [insert operating system of choice] and connect to it via a proprietary protocol. Your operating system can handle restarts in that case. Typically I think the multiple Tomcat containers is the easiest approach as it is simple to install and relatively easy to set up.
Good luck, it seems like a fun system administration problem. You also might be interested in checking out Quartz job scheduling as that might fit the bill for an intermittent service.
edit: a little more detail might provide some more detailed answers.
See this post. It's a simple tomcat-watchdog shell script.

How to avoid network call when REST client and server are on the same server

I have a web application in which two of the major components are the website (implemented in Groovy and Grails) and a backend RESTful web service (implemented using JAX-RS (Jersey) and Spring). Both of these will be running in Glassfish. The website will make calls to the RESTful web service. In many cases, these components will reside on separate servers, so the website will make calls over the network to the RESTful web service. If, however, I run both applications in the same Glassfish server, are there any optimizations that can be made to avoid the network call? In other words, I'm looking for some equivalent of EJB's remote/local interfaces for REST. Thanks!
Don't sweat the network call. Your traffic will generally never leave the local interface so you won't be consuming any bandwidth. You lose a bit of performance from serialization/deserialization, but you'll need to ask yourself if reducing the impact of this is worth developing a complicated proxy architecture. I think it most cases you'll find the answer to be no.
Not sure you will find any trivial solutions: you could of course add your own additional proxy layer, but I really wouldn't worry about it. Local network I/O (localhost or 127.0.0.1) is so heavily optimized anyway that you really won't notice.
Depending on your implementation Spring does support a number of remoting technologies (an old list is at http://static.springsource.org/spring/docs/2.0.x/reference/remoting.html), but you will find that key to all of these is the network transfer: they wrap it up in a variety of different ways but ultimately almost all turnkey remoting technologies drop into the network at some point in time. You may gain SOME efficiency by not having to use HTTP, but you will probably lose some of the loose coupling you gained by using Jersey.
If you are not too afraid to tightly couple maybe you can put the actual objects you are exposing via Jersey into a Glassfish-wide Spring context and invoke the methods directly: much tighter coupling though, so I'd say stick with the HTTP calls.
Yes, you can avoid a network call if your server and client both reside in the same JVM. You should be able to use Jersey Client API to create your own implementation of Connector to override default HTTP calls and handle request/response. Here is the blog that can get you started - http://www.theotherian.com/2013/08/jersey-2.0-server-side-client-in-memory-connector.html
IMHO, an unnecessary network overhead should be avoided at all cost. Even though this overhead would be only a few milliseconds, but while building features for your web application, you would increase such services call and all these milliseconds will add up to a good amount of latency on your application.

Categories