Mock SOAP request and response - java

For mocking currently we are recording SOAP request and response on file system with specific folder structure such as
Request folder
test1_request.xml
test2_request.xml
test3_request.xml
Response folder
test1_response.xml
test2_response.xml
test2_response.xml
When we run our test suite first we scan through these directory and store file content in a hashmap e.g.
Map.put(request, response)
Once all file contents are stored in map we start executing our test cases. In this process we construct the soap Request and pass it to our controller which in turn call this map and find a corresponding response for the request.
Now problem is over a period of time we have accumulated thousands of test cases and req/res which is slowing down the overall test execution process. For your information we have integrated this into our build process so everytime build is triggered we execute all our unit tests.
Any design recommendation to improve it?
I was thinking index these req/res files using solr or lucene but not sure if they provide any map machenism where in I pass soap request and get the matching response.

In case an incoming request must be completly equal to the cached request you can create a hash for the cached request and name the response files accordingly.
In your controller you can then create a hash for the request and you will directly find the response just opening the correct file.
Alternativly you can create a csv/properties file with "request hash" to "response filename" and just load this file. Should be much faster then always loading all requests and responses. This is more or less a simple index, lucene/solr should be really too much for just this use-case.

Related

Spring REST - Proper PUT functionality when resource does not already exist

I am building a REST API using Spring and implementing the PUT functionality. I am trying to handle the scenario in which the client tries to PUT to a uri where the resource does not already exist. In this scenario, per the PUT spec, a new resource should be created at that ID. However because of the ID generation strategy I am using (#GeneratedValue(strategy = GenerationType.IDENTITY)), I cannot create resources with IDs out of sequence. The database must use the next available value. However, according to the w3 spec on PUT...
If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.
If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.
In this case, I can do neither of these. I cannot create a new resource at the existing URI due to the ID generation restrictions, and I cannot send a 301 Moved Permanently response because according to How do I know the id before saving an object in jpa it is impossible to know the next ID in a sequence before actually persisting the object. So I would have no way of telling the client what URI to redirect to in order to properly create the new resource.
I would imagine this problem has been solved many times over because it is the standard PUT functionality, yet I am having trouble finding any other people who have tried to do this. It seems most people just ignore the "create new resource" part of PUT, and simply use it as update only.
What I want to do is just go ahead and create the new resource, and then send the 301 Moved Permanently to redirect the client to the true location of the created resource - but as we see above, this violates the definition of PUT.
Is there a spring-y way to solve this problem? Or is the problem unsolved, and the true standard practice is to simply not allow creation of new resources via PUT?
If the server cant processes the request due to an error in the request, just return a 400.
400 Bad Request -
The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).

How to keep API Restful when GET request requires sizable JSON payload?

I'm building a java REST API using JAX-RS and to complete a GET request for a zip file I need a rather sizeable chunk of JSON to complete it. I'm not terribly experienced with REST but I do know that GET requests shouldn't have a request body and a POST shouldn't be returning a resource. So I guess my question is, how do I complete a request that contains JSON (currently in the message body) and expects a zip file in the response while keeping the application RESTful? It may be worth noting that the JSON could also contain a password
I have used POST for similar scenarios. This is a common scenarios for SEARCH operations where there is a need to send json data in request. Though using POST for getting an object is not as per REST standards, I found that to be the most suitable given the options available.
You can send body in GET requests, but that is not supported by all frameworks/tools/servers. This link discusses that in detail.
If you use POST for the operation, you can use https to send confidential information in the body.
You can think that your REST API exposes a virtual file system and the zip file you mentioned is just one resource in that VFS and have files in a certain directory to represent queries of that file system. Then you can create a new query object by sending a POST request to the queries directory, specifying all query parameters you need, such as chunk size and the path of the zip file in the VFS.
The virtual file system I am referring to is actually a directory containing other directories and files that can represent real files on the disk or metadata records in a database.
For example, say you start with the following directory layout in the VFS:
/myvfs
/files
/archive.zip
/queries
To download the archive.zip file you can send a simple GET request:
// Request:
GET /myvfs/files/archive.zip
But this will stream the entire file at once. In order to break it in parts, you can create a query in which you want to download chunks of 1MB:
// Request:
POST /myvfs/queries/archive.zip
{
chunk_size: 1048576
}
// Response:
{
query_id: 42,
chunks: 139
}
The new query lives at the address /myvfs/queries/archive.zip/42 and can be deleted by sending a DELETE request to that URL.
Now, you can download the zip file in parts. Note that the creation of the query does not actually create smaller files for each part, it only provides information about the offsets and the size of the chunks, information that can be persisted anywhere, from RAM to databases or plain text files.
To download the first 1MB chunk of the zip file, you can send a GET request:
GET /myvfs/queries/archive.zip/42/0
As a final note, you should also be aware that the query resource can be modeled to accommodate other scenarios, such as dynamic ranges of a certain file.
P.S. I am aware that the answer is not as clear as it should and I apologize for that. I will try to come back and refine it, as time permits.

jmeter - how to build a request out of a response's results?

I'm looking into Jmeter to load test a webapp.
What is done in the real app when a user clicks a button is :
1. an http request is sent to a server and the response contains a list of ids.
2. another request which is formulated by the list of ids is sent to server.
I'm interested in the overall performance of both steps.
for example:
send request to http://server.com/getsomething
I get a json looks like:
{"ids":[11,22,33,44,55,66]}
I take the ids and build another request like http://server.com/getSomethingElse?
ids=11,22,33,44,55,66
How can I simulate a test like this in jmeter?
You will have to do something of following sort.
Thread group
HTTP Sampler 1 (Send request to http://server.com/getsomething)
(one ore more) Regular Expression extractor post processor (Extract IDs).
HTTP Sampler 2 (2nd request http://server.com/getsomethingElse?IDs)
Tree view listener (To see whats going on)
You may find following beginners jmeter screen cast helpful.
http://my.kpoint.com/kapsule/gcc-e1bad3ad-61cf-4620-9733-e44a74af8a3e/t/jmeter-tutorial-regex-extractor-basics

serving GWT permutations from appengine blob store - XSRF not found

In trying to serve GWT permutations out of the blob store in order to escape the AppEngine hard limit of 150 mb for static files, I've succeed in doing so for "html" and image files "jpeg, png, .etc" and other .rpc calls, but am hung up on XSRF calls.
In the server logs, I see:
The serialization policy file '/theapplication/CCA65B31464BDB27545C23C142FEEEF8.gwt.rpc' was not found;
My upload log shows it was uploaded /CCA65B31464BDB27545C23C142FEEEF8.gwt.rpc : HTTP/1.1 200 OK
The request url shows http://14.applicationXYZ.appspot.com/xsrf
the RequestPayload shows: http://14.applicationXYZ.appspot.com/theapplication/|CCA65B31464BDB27545C23C142FEEEF8|com.google.gwt.user.client.rpc.XsrfTokenService|getNewXsrfToken|1|2|3|4|0|
Other rpc calls are resolving (via a server filter is looking for /theapplication and mapping the requests to a blob to serve) as in the following case where an rpc call is made without an Xsrf request (as the user is not logged in yet)
req url -- http://14.applicationXYZ.appspot.com/someRPCCall
RequestPayload -- http://14.applicationXYZ.appspot.com/theapplication/|62D7E6737056C685E10947B640409549|com.abc.client.rpc.Service|doWork|java.lang.String/2004016611|java.lang.Boolean/476441737|wwwerr|1|2|3|4|3|5|5|6|7|7|6|0|
So, I have two questions:
1) why is XSRF call failing to return the appropriate blob, ie. why doesn't the xrsf call get handled by the filter the way other url calls to /theapplication/* do?
2) What can I do about it?
3) Also, I tried setting the content type to "text/x-gwt-rpc; charset=UTF-8 and also as unspecified when I uploaded the blob. Anyone know what the content type should be for *.gwt.rpc in case I do get the xrsf working? Could having the wrong content type be causing the trouble?
***note applicationXYZ is not the real name so no the links won't work.
OK /xsrf is mapped to a servlet as well, so if the filter returns a blob without passing on the filter, it seems it won't reach the servlet.
Anyway, it's easy enough just to upload the few .rpc files as normal and not serve them as blobs.

AS2: Does xml.sendAndLoad use POST or GET?

All,
I'm trying to find out, unambiguously, what method (GET or POST) Flash/AS2 uses with XML.sendAndLoad.
Here's what the help/docs (http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002340.html) say about the function
Encodes the specified XML object into
an XML document, sends it to the
specified URL using the POST method,
downloads the server's response, and
loads it into the resultXMLobject
specified in the parameters.
However, I'm using this method to send XML data to a Java Servlet developed and maintained by another team of developers. And they're seeing log entries that look like this:
GET /portal/delegate/[someService]?svc=setPayCheckInfo&XMLStr=[an encoded version of the XML I send]
After a Google search to figure out why the POST shows up as a GET in their log, I found this Adobe technote (http://kb2.adobe.com/cps/159/tn_15908.html). Here's what it says:
When loadVariables or getURL actions are
used to send data to Java servlets it
can appear that the data is being sent
using a GET request, when the POST
method was specified in the Flash
movie.
This happens because Flash sends the
data in a GET/POST hybrid format. If
the data were being sent using a GET
request, the variables would appear in
a query string appended to the end of
the URL. Flash uses a GET server
request, but the Name/Value pairs
containing the variables are sent in a
second transmission using POST.
Although this causes the servlet to
trigger the doGet() method, the
variables are still available in the
server request.
I don't really understand that. What is a "GET/POST hybrid format"?
Why does the method Flash uses (POST or GET) depend on whether the data is sent to a Java servlet or elsewhere (e.g., a PHP page?)
Can anyone make sense of this? Many thanks in advance!
Cheers,
Matt
Have you try doing something like that :
var sendVar=new LoadVars();
var xml=new XML("<r>test</r>");
sendVar.xml=xml;
sendVar.svc="setPayCheckInfo";
var receiveXML=new XML();
function onLoad(success) {
if (success) {
trace("receive:"+receiveXML);
} else {
trace('error');
}
}
receiveXML.onLoad=onLoad;
sendVar.sendAndLoad("http://mywebserver", receiveXML, "POST");
The hybrid format is just a term Macromedia invented to paint over its misuse of HTTP.
HTTP is very vague on what you can do with GET and POST. But the convention is that no message body is used in GET. Adobe violates this convention by sending parameters in the message body.
Flash sends the same request regardless of the server. You have problem in Servlet because most implementation (like Tomcat) ignores message body for GET. PHP doesn't care the verb and it processes the message body for GET too.

Categories