invalid characters in JSON message after using await/job in play framework 1.2.5 - playframework-1.x

I am using play framework 1.2.5 jobs - after await, I send a message to the web UI in JSON format. The same JSON logic works fine when not using jobs - however, after using jobs and await, the JSON message appears to contain invalid characters (client side javascript does not recognize it as valid JSON anymore). The browser does not render the garbled/invalid characters - I will try using wireshark and see if I can add more details. Any ideas on what could be causing this and how best to prevent this? Thanks in advance (I'm reasonably sure its my code causing the problem since I can't be the first one doing this). I will also try to test using executors/futures instead of play jobs and see how that goes.
Promise<String> testChk = new TestJobs(testInfo, "validateTest").now(); //TestJobs extends Job<String> & I'm overriding doJobWithResult. Also, constructor for TestJobs takes two fields (type for testInfo & String)
String testChkResp = await(testChk);
renderJSON(new TestMessage("fail", "failure message")); //TestMessage class has two String fields and is serializable
Update: I am using gson & JDK1.6
Update It seems that there is a problem with encoding whenever I use play jobs and renderJSON.
TestMessage: (works when not using jobs)
import java.io.Serializable;
public class TestMessage {
public String status;
public String response;
public TestMessage() {
}
public TestMessage(String status, String response) {
this.status = status;
this.response = response;
}
}
Update:
Even using the following results in utf-8 impact when using while relying on jobs.
RenderJSON("test");

Sounds like it could be a bug. It may be related to your template - does it specify the encoding explicitly?
What format is the response? You can determine this by using the inspector in chrome or Web Console in Firefox.
(Though I certainly agree the behaviour should be consistent - it may be worth filing a bug here: http://play.lighthouseapp.com/projects/57987-play-framework/tickets )

It's a workaround; first reset the outputstream then render.
response.reset();
response.contentType="application/json; charset=utf-8";
renderJSON("play has some bugs")

I was able to use futures & callables with executors and the same code as mentioned above works (using play 1.2.5). The only difference was that I was not explicitly using play jobs (and hence the issue does not appear to be related to gson).

Related

DCMTK Understand the "DIMSE No valid Presentation Context ID" error

I'm currently developing a simple application for querying/retrieving data on a PACS. I use DCMTK for this purpose, and a DCM4CHEE PACS as test server.
My goal is to implement simple C-FIND queries, and a C-MOVE retrieving system (coupled with a custom SCP to actually download the data).
To do so, I've created a CustomSCU class, that inherits the DCMTK DcmSCU class.
I first implemented a C-ECHO message, that worked great.
Then, I tried to implement C-FIND requesting, but I got the error "DIMSE No valid Presentation Context ID" (more on that in the next paragraph) from my application, but no other log from DCM4CHEE. I've then used the command tool findscu (from dcmtk) to see if there was some configuration issue but the tool just worked fine. So in order to implement my C-FIND request, I've read the source of findscu (here) and adapted it in my code (meaning that i'm not using DcmSCU::sendCFindRequest but the class DcmFindSU).
But now, i'm facing the same problem with C-MOVE request. My code is pretty straight-forward :
//transfer syntaxes
OFList<OFString> ts;
ts.push_back(UID_LittleEndianExplicitTransferSyntax);
ts.push_back(UID_BigEndianExplicitTransferSyntax);
ts.push_back(UID_LittleEndianImplicitTransferSyntax);
//sop class
OFString pc = UID_MOVEPatientRootQueryRetrieveInformationModel;
addPresentationContext(pc, ts);
DcmDataset query;
query.putAndInsertOFStringArray(DCM_QueryRetrieveLevel, "PATIENT");
query.putAndInsertOFStringArray(DCM_PatientID, <ThePatientId>);
OFCondition condition = sendMOVERequest(findPresentationContextID(pc, ""), getAETitle(), &query, nullptr);
return condition.good();
I've also tried using UID_MOVEStudyRootQueryRetrieveInformationModel instead of UID_MOVEPatientRootQueryRetrieveInformationModel, with the same result : my application shows the error
DIMSE No valid Presentation Context ID
As I understand, a presentation context is concatenation of one or more transfer syntax and one SOP class. I read that the problem could come from the PACS that won't accept my presentation contexts. To be sure, I used the movescu tool (from DCMTK). It worked, and I saw this in the logs from de server DCM4CHEE :
received AAssociatedRQ
pc-1 : as=<numbers>/Patient Root Q/R InfoModel = FIND
ts=<numbers>/Explicit VR Little Endian
ts=<numbers>/Explicit VR Big Endian
ts=<numbers>/Implicit VR Little Endian
That means that the movescu tool does a find before attempting an actual move ?
Therefore, I changed my application context creation with :
OFList<OFString> ts;
ts.push_back(UID_LittleEndianExplicitTransferSyntax);
ts.push_back(UID_BigEndianExplicitTransferSyntax);
ts.push_back(UID_LittleEndianImplicitTransferSyntax);
OFString pc1 = UID_FINDPatientRootQueryRetrieveInformationModel;
OFString pc = UID_MOVEPatientRootQueryRetrieveInformationModel;
addPresentationContext(pc1, ts);
addPresentationContext(pc, ts);
(also tried study root)
But this didn't do the trick.
The problem seems to lie on the client side, as findPresentationContextID(pc, ""); alwasy return 0, no matter what.
I don't feel like it's possible to adapt the code of the movescu tool, as it appears to be very complex and not adequat for simple retrieve operations.
I don't know what to try. I hope someone can help me understand what's going on. That's the last part of my application, as the storage SCP already works.
Regards
It looks like you are not negotiating the association with the PACS.
After adding the presentation contexts and before sending any command, the SCU must connect to the PACS and negotiate the PresentationContexts with DcmSCU::initNetwork and then DcmSCU::negotiateAssociation.

Problems with MSF4J and #MatrixParam

Folks, I have found what seems to be a problem with / (bug in ?) MSF4J as including an #MatrixParam annotated variable in a URI causes the affected (micro)service to either 'hang' indefinitely, or if accessed via a browser, to give a "404 Not Found" message for the path/endpoint, even when correct.
Here is a code fragment that illustrates the problem - it compiles ok (eclipse/maven) and deploys without errors using microservicesrunner() in the usual way.
package org.test.service;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
#Path("books")
public class MPTest { // MatrixParam Test
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/query")
// method to respond to 'GET' requests
public Response getListOfBooks(#MatrixParam("Author") String author) {
// do something in here to get book data from DB and sort by titles
List<String> titles = .......;
return Response.status(200) .entity("List of Books by " +author+ "ordered by title " + titles).build();
}
}
With this code fragment, accessing the URL "(host:8080)/books/query;Author=MickeyMouse" should cause a list of books by that author to be retrieved from the DB (I have omitted the actual code that does so for clarity, as it is not relevant to this post).
However, it does not get there, so that code isnt executed. As far as I can tell with a debugger, no #MatricParam value is retrieved - it remains null until the process times out. Things like curl and wget just hang until they time out, and from a browser, the best I can get is a 404 not found error for the URI, even though it is valid.
However, if I replace the #MatrixParam with a #PathParam it works perfectly, and can I get the URL string retrieved in its entirity. The URI that I get is as expected - no odd hex characters, no typos, and so forth. The URI entered is what you get back. So, no problem there.
Behaviour is also consistent across platforms (couple of flavours of Linux, and three versions of Windoze), so it is not anything to do with the OS itself. Similarly, I get the same behavior with multiple clients and tools, so it isnt a problem there either.
So, it appears to be a problem within the MSF4J framework / domain, and I could use some support / help / suggestions here as I've reached the point of tearing my hair out..... Any ideas, folks?
The only reference I can find to a similar problem was closed as 'off topic' without a reply (see Rest API Matrix param annotation) so I think that this needs re-opening as it seems to be a genuine problem....
Regards, and thanks in advance for any help,
Rick
#MatrixParam is not supported with MSF4J at the moment. You can create a GitHub issue. So we can implement that support in future releases.

Dynamic messages with gettext (AngularJS)

I have a application with a Django backend and an AngularJS front-end.
I use the angular-gettext plugin along with Grunt to handle translations.
The thing is, I sometimes received dynamic strings from my backend through the API. For instance a MySQL error about a foreign key constraint or duplicate key entry.
How can I add this strings to the .pot file or non harcoded string in general ?
I've tried to following but of course it cannot work :
angular.module('app').factory('HttpInterceptor', ['$q', '$injector', '$rootScope', '$cookieStore', 'gettext', function ($q, $injector, $rootScope, $cookieStore, gettext) {
responseError: function (rejection) {
gettext('static string'); //it works
gettext(rejection.data.error); //does not work
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
})();
One solution I could think of would be to write every dynamic strings into a JSON object. Send this json to server and from there, write a static file containing these strings so gettext can extract them.
What do you suggest ?
I also use angular-gettext and have strings returned from the server that need to be translated. We did not like the idea of having a separate translation system for those messages so we send them over in the default language like normal.
To allow this to work we did two things. We created a function in our backend which we can call to retrieve all the possible strings to translate. In our case it's mainly static data that only changes once in a while. Ideally this would be automated but it's fine for now.
That list is formatted properly through code into html with the translate tag. This file is not deployed, it is just there to allow the extraction task to find the strings.
Secondly we created a filter to do the translation on the interpolated value, so instead of translating {{foo}} it will translate the word bar if that's was the value of foo. We called this postTranslate and it's a simple:
angular
.module('app')
.filter('postTranslate', ['gettextCatalog', function (gettextCatalog) {
return function (s) {
return gettextCatalog.getString(s);
};
}]);
As for things that are not in the database we have another file for those where we manually put them in. So your error messages may go here.
If errors are all you are worried about though, you may rather consider not showing all the error messages directly and instead determine what user friendly error message to show. That user friendly error message is in the front end and therefore circumvents all of this other headache :)

Apply HTTP basic authentication to jax ws (HttpSpiContextHandler) in embedded Jetty

There are some similar questions for earlier versions of Jetty (pre 9) but none that address this specific problem :
Server server = new Server();
System.setProperty("com.sun.net.httpserver.HttpServerProvider",
JettyHttpServerProvider.class.getName());
JettyHttpServer jettyServer = new JettyHttpServer(server, true);
Endpoint endpoint = Endpoint.create(new SOAPService()); // this class to handle all ws requests
endpoint.publish(jettyServer.createContext("/service")); // access by path
server.start()
Simplified code example above to show the only way that I have found to bridge between Jetty and incoming soap requests to my jax-ws service. All settings are in code with no web.xml, this is part of a larger solution that has multiple contexts and connections for different purposes (servlets etc..)
I have tried to add a handler class to the jettyServer.createContext("/service",new handler()) to see if I can perform a header extraction to simulate basic auth but it never gets executed.
My problem is that i cannot find a way to specify, by code against the Jetty server, to use basic authentication. Using the setSecurityHandler method of a ServletContextHandler is easy and works great for other contexts, i just can't figure out how to use this concept for the jax-ws service.
Any help would be much appreciated.
p.s. SSL is already implemented, I just need to add http basic auth.
For anyone else that may of come across the same problem here is the answer that i stumbled on eventually.
final HttpContext httpContext = jettyServer.createContext("/service");
com.sun.net.httpserver.BasicAuthenticator a = new com.sun.net.httpserver.BasicAuthenticator("") {
public boolean checkCredentials (String username, String pw)
{
return username.equals("username") && pw.equals("password");
}
};
httpContext.setAuthenticator(a);
endpoint.publish(httpContext);//access by path
You can expand the checkCredentials for something a bit more sophisticated of course, but this shows the basic working method.

How to consume SOAP Webservices in Blackberry

I am working on a blackberry application. I need to call soap webservices, but I am unable to do so, and am getting null as a response. Following is my code:
private static final String CONNECTION_PARAMS = ";deviceside=true";
SoapObject request = new SoapObject("http://service.action.com/",
"findActiveSecurities");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
HttpTransportBasicAuth ht =
new HttpTransportBasicAuth("http://myurl.com/ebclient/services/MobileClientService?wsdl"+CONNECTION_PARAMS,
"myusername",
"mypassword");
PropertyInfo propInfo=new PropertyInfo();
propInfo.type=PropertyInfo.INTEGER_CLASS;
//adding parameters
request.addProperty("arg0","NSE");
request.addProperty("arg1","0");
request.addProperty("arg2","100");
envelope.setOutputSoapObject(request);
try {
ht.call(SOAP_ACTION, envelope);
result = (SoapObject)envelope.getResponse();
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
I am getting null as a result.Please have a look at the code and help me to correct it.
Thanks in advance
Actually the problem was instead of passing 0 and 100 as String ...
request.addProperty("arg0","NSE");
request.addProperty("arg1","0");
request.addProperty("arg2","100");
I use
request.addProperty("arg0","NSE");
request.addProperty("arg1",new Integer(0));
request.addProperty("arg2",new Integer(1000));
also this link helped me.
also before asking this question I was facing some problem that the Simulator was not recognizing a Library. It shows error message something like "there is no library Ksoap2_j2me.jar" - resolved from this link.
Sorry for poor English but I think this can save time of some other developer.
It's hard to tell from what you're posted, but my guess is that you're having some kind of network problem. I'm guessing that you initialize result = null;, and then your call to ht.call() throws an IOException, leaving result null.
You're using ksoap2, which is a library written for generic J2ME clients. However, BlackBerry networking doesn't work exactly like all other J2ME platforms.
You are controlling the BlackBerry network transport with your connection params string, which is hardcoded:
private static final String CONNECTION_PARAMS = ";deviceside=true";
Unfortunately, this string suffix may not be right for all network conditions (or any, if you don't have device APN settings correct).
I think you have a couple choices:
1. Connection Suffix Strings
You can try dynamically choosing the right suffix string, depending on conditions when your app runs. This can allow the device, for example, to connect via Wi-Fi if it's available, or via BES if that's available. Developers new to BlackBerry may be surprised that app code needs to worry about this (read here for more, or watch this).
If you want to simply replace CONNECTION_PARAMS with a dynamic string, you might check out the implementation here.
2. ConnectionFactory
In OS 5.0, BlackBerry added the ConnectionFactory class, which was a big improvement over the old way of having to assemble connection strings. If you only need to support OS 5.0 and greater, you might choose to rewrite the code to use ConnectionFactory.
Since you have access to the ksoap source code, you could change it. It looks like the connection code is in ServiceConnectionMidp.java:
public ServiceConnectionMidp(String url) throws IOException {
connection = (HttpConnection) Connector.open(url, Connector.READ_WRITE, true);
}
Instead of attaching connection parameters to the url passed to this class, you could change the class to get the connection from a ConnectionFactory, customized to support the network transports you want.
Doing this means that if you ever want to update your code to use a new version of ksoap2, you'll need to make these modifications again. However, given the future of BlackBerry Java, that seems like a reasonable compromise to make.