Grails atmosphere plugin browser hang after few requests - java

Using atmosphere plugin in grails, after a few requests to server (after few pages of navigation) the browser is not rendering any pages and it is just loading. Other browser in other systems works fine. The code to connect to the server is placed in common layout page.
server code:
def onRequest = { event ->
def userBroadcasters= ServletContextHolder.servletContext.getAttribute('userBroadcasters')
def uid=event.getRequest().session.user?.id
if(!userBroadcasters){
userBroadcasters=[:]
}
Broadcaster privateChannel = BroadcasterFactory.getDefault().lookup("/userChannel"+uid, true);
privateChannel.addAtmosphereResource(event)
userBroadcasters.put(uid,privateChannel)
ServletContextHolder.servletContext.setAttribute('userBroadcasters',userBroadcasters)
event.suspend()
//println ServletContextHolder.servletContext.getAttribute('userBroadcasters')
//println "Inside onRequest!"
}
client code in common layout:
function callback(response) {
if (response.status == 200 && response.responseBody.length > 0) {
//action
}
}
var location = '${request.contextPath}/atmosphere/mx';
var request = {transport: "streaming", fallbackTransport: 'long-polling', contentType: "application/json",connectTimeout:4000};
$.atmosphere.subscribe(location, callback, request);

Related

Running integration tests for a spring-boot REST service using gradle

I am currently trying to setup integration test framework for a REST service which is built on:
Spring-boot
Gradle
Jetty
I was able to use spring-boot integration test framework along with spring-boot junit runner to bring up the app context and run the tests successfully.
The next thing that I was trying to do was to have a gradle task which will do the following:
Build the jar(not war)
Start jetty and deploy the jar
Run a set of test-cases against this jar.
Stop jetty
=> I tried using the 'jetty' plugin. But it does not seem to be supporting jar files.
=> I then tried using the JavaExec task to run the jar and then run the tests, but then I couldn't find a straight-forward way to stop the jar process after the tests are done.
=> The same issue with the Exec type task.
So, I have two questions regarding this:
Is there a way to achieve the above said form of integration testing using gradle.
Is this way of integration-testing recommended or is there a better way of doing it?
Any thoughts and insights are much appreciated.
Thanks,
There are different ways to achieve what you want. The approach I helped with at a client relied on the /shutdown URL provided by Spring Boot Actuator. Important If you use this approach, be sure to either disable or secure the /shutdown endpoint for production.
Within the build file you have two tasks:
task startWebApp(type: StartApp) {
dependsOn 'assemble'
jarFile = jar.archivePath
port = 8080
appContext = "MyApp"
}
task stopWebApp(type: StopApp) {
urlPath = "${startWebApp.baseUrl}/shutdown"
}
You should make sure that your integration tests depend on the startWebApp tasks and they should be finalised by the stop task. So something like this:
integTest.dependsOn "startWebApp"
integTest.finalizedBy "stopWebApp"
Of course, you need to create the custom task implementations too:
class StartApp extends DefaultTask {
static enum Status { UP, DOWN, TIMED_OUT }
#InputFile
File jarFile
#Input
int port = 8080
#Input
String appContext = ""
String getBaseUrl() {
return "http://localhost:${port}" + (appContext ? '/' + appContext : '')
}
#TaskAction
def startApp() {
logger.info "Starting server"
logger.debug "Application jar file: " + jarFile
def args = ["java",
"-Dspring.profiles.active=dev",
"-jar",
jarFile.path]
def pb = new ProcessBuilder(args)
pb.redirectErrorStream(true)
final process = pb.start()
final output = new StringBuffer()
process.consumeProcessOutputStream(output)
def status = Status.TIMED_OUT
for (i in 0..20) {
Thread.sleep(3000)
if (hasServerExited(process)) {
status = Status.DOWN
break
}
try {
status = checkServerStatus()
break
}
catch (ex) {
logger.debug "Error accessing app health URL: " + ex.message
}
}
if (status == Status.TIMED_OUT) process.destroy()
if (status != Status.UP) {
logger.info "Server output"
logger.info "-------------"
logger.info output.toString()
throw new RuntimeException("Server failed to start up. Status: ${status}")
}
}
protected Status checkServerStatus() {
URL url = new URL("$baseUrl/health")
logger.info("Health Check --> ${url}")
HttpURLConnection connection = url.openConnection()
connection.readTimeout = 300
def obj = new JsonSlurper().parse(
connection.inputStream,
connection.contentEncoding ?: "UTF-8")
connection.inputStream.close()
return obj.status == "UP" ? Status.UP : Status.DOWN
}
protected boolean hasServerExited(Process process) {
try {
process.exitValue()
return true
} catch (IllegalThreadStateException ex) {
return false
}
}
}
Note that it's important to start the server on a thread, otherwise the task never ends. The task to stop the server is more straightforward:
class StopApp extends DefaultTask {
#Input
String urlPath
#TaskAction
def stopApp(){
def url = new URL(urlPath)
def connection = url.openConnection()
connection.requestMethod = "POST"
connection.doOutput = true
connection.outputStream.close()
connection.inputStream.close()
}
}
It basically sends an empty POST to the /shutdown URL to stop the running server.

Javascript: Disable button based on server status

I'm very new to Javascript and I have a button that need to be constantly checked against whether a server is active or not.
I'm using the Play framework based in Java. I already have a class ServerStatus that returns whether a service is healthy or not but I am not sure how to link this into my page which contains the button.
Basically, what I want is that if the server goes down then I want the button disabled so that the user cannot use it while the server is unavailable.
I looked a bit at Websockets and that looks really complex. I wasn't sure if there is a simpler way.
EDIT
Using Websockets: I had a read around and it seems I need to use the onmessage event. I found some sample code but I am not sure how to put this into my (document).ready function.
Below I have some code:
$(document).ready(function(){
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket;
var chatSocket = new WS("routes");//This does not seem to accept any #routes
var lastState = 'unknown';
chatSocket.onmessage = function(e){
var server_message = e.data;
//do something here about enabling and disabling
console.log(server_message);
}
});
function disable()
{
//disable all buttons
}
function enable()
{
//enable all buttons
}
I am lost as to how to add the websocket here.
I am borrowing heavy from this similar question and answer
The basic code is here:
var isNotWorking = false;
var myFunc = function(){
$.ajax({url: "YOUR_URL_HERE",
type: "HEAD",
timeout:1000,
statusCode: {
200: function (response) {
//alert('Working!');
isNotWorking =false;
},
400: function (response) {
//alert('Not working!');
isNotWorking = true;
},
0: function (response) {
//alert('Not working!');
isNotWorking = true;
}
}
});
$('#mybutton').prop('disabled', isNotWorking);
doSetTimeOut();
}
var doSetTimeOut = function(){
setTimeout(function(){
myFunc();
}, 1000);
}
doSetTimeOut();
See a working JS fiddle here

Firefox, websockets and odd behaviours

Background:
Using WebSockets with JavaScript + Play! framework (2.2).
Can send and receive data fine in Chrome.
Can only receive data (from server) in Firefox as send() doesn't trigger any callbacks.
In addition to the send issue, and in Firefox only again, the tab for the page is always stuck on "connecting" while the spinner keeps spinning (see figure 1).
Misbehaving Browser:
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0)(Firefox 24.0)
(Figure 1. Firefox tab after page has loaded and data is shown)
Any time I refresh the web page, I receive the error below, attributed to the constant page loading behaviour I'm sure.
The connection to ws://localhost:9000/ was interrupted while the page was loading.
The entire JavaScript code:
$(function() {
var chatSocket = new WebSocket("#routes.Application.getMetaData().webSocketURL(request)");
var sendMessage = function() {
chatSocket.send(JSON.stringify({
id: "unique",
name: "a name",
age: 22
}));
}
var receiveEvent = function(event) {
var data = JSON.parse(event.data)
document.write(data.age);
document.write(data.name);
document.write(data.message);
document.write("\n");
sendMessage();
chatSocket.close();
}
chatSocket.onmessage = receiveEvent
})
Now In the past, I've been trying with MozWebSocket instead of the standard WebSocket, but I get nothing rendered on screen using that module therefore unless there is an angle I've missed, WebSocket is the better one to use.
The relevant Play! block:
public static WebSocket<JsonNode> getMetaData() {
return new WebSocket<JsonNode>() {
// Called when the Websocket Handshake is done.
public void onReady(WebSocket.In<JsonNode> in, WebSocket.Out<JsonNode> out) {
// For each event received on the socket,
in.onMessage(new Callback<JsonNode>() {
#Override
public void invoke(JsonNode jsonNode) {
System.out.println("Message Incoming!");
System.out.println(jsonNode.get("id"));
System.out.println(jsonNode.get("name"));
System.out.println(jsonNode.get("age"));
}
});
// When the socket is closed.
in.onClose(new Callback0() {
public void invoke() {
System.out.println("Disconnected");
}
});
ObjectNode node = Json.newObject();
node.put("message", "hello");
node.put("name", "client");
node.put("age", 1);
out.write(node);
//same result commented/uncommented
out.close();
}
};
}
So in Chrome, the flow would be:
document.write(...)
"Message Incoming!"
... JSON attributes
"Disconnected"
But in Firefox, the flow is:
document.write(...)
"Disconnected"
Any help in diagnosing these problems would be greatly appreciated. I have no intention of supporting IE, but having both Mozilla and Chrome working would be great.
Other JavaScript Warnings:
Below is a warning I occasionally get in Firefox's console while pointing at the "ws" protocol as the culprit. What its relevance is to my problem, I do not know.
Use of getPreventDefault() is deprecated. Use defaultPrevented instead.
You call document.write() after the document is loaded, which then implies document.open() which in turn replaces the document and by that unloads the old one and aborts stuff like timeouts or websockets.
Use something other than document.write() and you should be fine.

facebook login Server-side Apps with javascript sdk

I have searched stackoverflow for an full example or some blog that explains how to make facebook login Server-side Apps with javascript sdk
but didn't find anything.
I have searched developer.facebook.com site and the only thing i have got was a php example https://developers.facebook.com/docs/howtos/login/server-side-login/.
The problem is that i must use JavaScript.
Why should i want to do that?
The reason is that i want to upload files to the server(google-app-engine(Java Sdk)) and save them on the db with the facebook user id and retrieve them by his user id.
another question is, how can i debug my javascript code if he uploaded dynamically?what about code assist?
Well I can help you with this issue. If you need to use the JS SDK of FB, then you have to do everything on the client side or on browser, because Facebook doesn't have any support for Java on Server Side.
So I suggest you that you can authenticate user on client, define your scopes for accessing user profile, once authenticated by user you will get response as JSON Object which you can send using ajax to AppEngine Backend.
I am sharing my link where I used FB Login and accessing User's Profile Information along with his photos in albums and videos.
http://demositeunicfyp.appspot.com/fb-pictures.html
http://demositeunicfyp.appspot.com/facebook.html
You can Debug the JS Code in your browser to see what kind of response object you are getting back from Facebook APIs.
$(document).ready(function() {
// Initializing the Facebook SDK
FB.init({
appId : 'XXXXXXXXXXXXXXXX',
status : true,
cookie : true,
xfbml : true,
oauth : true
});
// Method to check if a user is looged in to FB or Not
FB.getLoginStatus(updateButton);
$("#logout").live("click", function(event) {
event.preventDefault();
// FB.getLoginStatus(updateButton);
FB.logout(function(response) {
$("#loginDiv").show();
$("#logoutDiv").hide();
});
});
$("#fbLoginButton").live("click", function(event) {
//event.preventDefault();
FB.getLoginStatus(updateButton);
});
function updateButton(response) {
var button = document.getElementById("fbLoginButton");
if (response.authResponse) {
// user is already logged in and connected
// button.innerHTML = 'Facebook Logout';
//$("#loginDiv").hide();
//$("#logoutDiv").show();
//window.location = '/confirm';
FB.api('/me', function(response) {
$("#userName").text(response.name);
$("#userEmail").text(response.email);
});
} else {
// user is not connected to your app or logged out
// button.innerHTML = 'Facebook Login';
button.onclick = function() {
FB.login(function(response) {
if (response.authResponse) {
// button.innerHTML = 'Facebook Logout';
$("#loginDiv").hide();
$("#logoutDiv").show();
FB.api('/me', function(response) {
$("#userName").text(response.name);
$("#userEmail").text(response.email);
});
} else {
//user cancelled login or did not grant authorization hence do nothing
}
}, {
scope : 'email,publish_actions'
});
}
}
}
});
Taken from JS.php in SDK download
<?php
require '../folderTo/facebook.php';
$facebook = new Facebook(array(
'appId' => '',
'secret' => '',
));
// See if there is a user from a cookie
$user = $facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('me?fields=photos'); } catch (FacebookApiException $e) {
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$user = null;
}
}
?>
<!DOCTYPE html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<body>
<?php if ($user) { ?>
Your user profile is
<pre>
<?php print htmlspecialchars(print_r($user_profile, true)) ?>
</pre>
<?php } else { ?>
<fb:login-button></fb:login-button>
<?php } ?>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId: '<?php echo $facebook->getAppID() ?>',
cookie: true,
xfbml: true,
oauth: true
});
FB.Event.subscribe('auth.login', function(response) {
window.location.reload();
});
FB.Event.subscribe('auth.logout', function(response) {
window.location.reload();
});
};
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
</body>
</html>
Working example here: http://slicethegreen.com/examples/js.php

HttpMessage.setMethod(HttpMessage.POST) is changed by GET, on BlockingSenderDestination

I am trying to migrate a Blackberry application from OS 6 to OS 7 (my app currently works on OS 6). Theoretically it should not cause any problems, but I found an issue that I still cannot resolve. When executing calls to web services (SOAP), I'm setting the HttpMessages to use the POST method, but when the call is executed, it arrives at the server as a GET. This is a big problem for me because the Sever with which am working doesn't support GET's (always results in an "Http 500 error"). This issue doesn't occur on the simulator, just on the device.
Do you know any workaround for this? Is it a problem with OS version? (See below for the code that I'm using).
Device
Model: Bold 9930
Carrier: Sprint
OS: 7.0 Bundle 1296 (v7.0.0.241, Platform 5.0.0.442)
Simulator (On the simulator side I don't have any problems)
Model: Bold 9930
OS: 7.0 Bundle 1962(v7.0.0.440, Sept_24_2011_signed, Platform 4.0.0.141)
public void run() {
context.setEnableBtnsend(false);
BlockingSenderDestination blockSendDest = null;
try {
URI uri = URI.create(URL_BASE);
blockSendDest
= (BlockingSenderDestination) DestinationFactory.getSenderDestination(
senderContext.getName(), uri);
if (blockSendDest == null) {
blockSendDest = DestinationFactory.createBlockingSenderDestination(
senderContext, uri);
}
ByteMessage requestMessage = blockSendDest.createByteMessage();
requestMessage.setTransportHeader("Content-Type", "text/xml;charset=UTF-8");
requestMessage.setTransportHeader("SOAPAction", "\"\"");
// getBodyRequest() -> Insert SOAP request, works fine, was tested on SOAP UI
requestMessage.setStringPayload(getBodyRequest());
((HttpMessage) requestMessage).setMethod(HttpMessage.POST);
blockSendDest.resume();
Message response = blockSendDest.sendReceive(requestMessage);
if (response != null) {
procesMessageResponse(response);
}
// ...
}
catch (Exception ex) {
handleException(ex);
}

Categories