Apache - Tomcat 7 WebSocket do not start up - spring

My tomcat version is 7.0.107 with Apache 2.4.
I'm using Spring 4, Java 7 SDK
The issue that I cannot resolve is so complicated.
Once I setting up and start my project over https(ssl),
my application SocketHandler do not working at all.
public class SocketHandler extends TextWebSocketHandler implements InitializingBean {
private Set<WebSocketSession> sessionSet = new HashSet<WebSocketSession>();
public SocketHandler() {
super();
System.out.println("create SocketHandler instance!");
}
#Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
try {
super.afterConnectionClosed(session, status);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sessionSet.remove(session);
System.out.println("remove session!");
}
#Override
public void afterConnectionEstablished(WebSocketSession session) {
try {
super.afterConnectionEstablished(session);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sessionSet.add(session);
System.out.println("add session!");
}
#Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
try {
super.handleMessage(session, message);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("receive message:" + message.toString());
}
#Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
System.out.println("web socket error!"+ exception);
}
#Override
public boolean supportsPartialMessages() {
System.out.println("call method!");
return super.supportsPartialMessages();
}
public void sendMessage(String message) {
for (WebSocketSession session : this.sessionSet) {
if (session.isOpen()) {
try {
session.sendMessage(new TextMessage(message));
} catch (Exception ignored) {
System.out.println("fail to send message!" + ignored);
}
}
}
}
#Override
public void afterPropertiesSet() throws Exception {
Thread thread = new Thread() {
int i = 0;
#Override
public void run() {
while (true) {
try {
sendMessage("send message index " + i++);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
};
thread.start();
}
}
my serlvet.xml file
<websocket:handlers>
<websocket:mapping path="/socket/echo" handler="echoHandler"/>
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
<bean id="echoHandler" class="studyroom.util.SocketHandler" />
AS you can see, echoHandler(SocketHandler) is not starting up,
when I access my wss action :(
How can I start up my SocketHandler?
My client Script File is like below :
var wsUri = "wss://example.com/socket/echo";
var websocket;
function init() {
output = document.getElementById("output");
}
function send_message() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt);
};
websocket.onmessage = function(evt) {
onMessage(evt);
};
websocket.onerror = function(evt) {
onError(evt);
};
}
function onOpen(evt) {
writeToScreen("Connected to Endpoint!");
doSend(textID.value);
}
function onMessage(evt) {
alert(evt.data);
writeToScreen("Message Received: " + evt.data);
}
function onError(evt) {
writeToScreen('ERROR: ' + evt.data);
}
function doSend(message) {
writeToScreen("Message Sent: " + message);
websocket.send(message);
websocket.close();
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
HTML FILE :
<div style="text-align: center;">
<form action="">
<input onclick="send_message()" value="Send" type="button">
<input id="textID" name="message" value="Hello WebSocket!" type="text"><br>
</form>
</div>
<div id="output"></div>

Related

How to schedule service in Apache Felix?

I have deployed some Declarative Services OSGI in my bundle. After my bundle is started, these Services are activated and do some code in run() of Thread. However, I would like to schedule the time to start the run().
#Component(name = "ABC"
,immediate = true
,enabled = true)
public class test {
private volatile boolean isStarted;
#Activate
public void activate() {
System.out.println("activate");
final Thread t = new Thread() {
public void run() {
runIt();
}
};
t.setDaemon(true);
isStarted = true;
t.start();
}
#Deactivate
public void deactivate() {
System.out.println("DEactivate");
isStarted = false;
}
private void runIt() {
while (isStarted) {
System.out.println("OK");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Java CompletableFuture - main class not terminated

I am trying to implment CompletableFuture which invokes a dummy callback method when completed.
However, after adding CompletableFuture.get() method my main class doesn't terminate.
I tried replacing CompletableFuture.get() with Thread.sleep(5000) but it doesn't seem to be right approach.
Please suggest what is causing CompletableFuture.get() to keep blocking even if the thread is complete.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.IntStream;
public class CallableAsyncWithCallBack {
public static void main(String[] args) throws InterruptedException {
CompletableFuture<String> compFuture=new CompletableFuture<String>();
compFuture.supplyAsync(()->{
//Compute total
long count=IntStream.range(Integer.MIN_VALUE, Integer.MAX_VALUE).count();
return ""+count;
}).thenApply(retVal->{
try {
return new CallBackAsynchClass(retVal).toString();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
);
System.out.println("Main Thread 1");
try {
compFuture.get();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("Lock cleared");
}
}
class CallBackAsynchClass
{
String returnVal="";
public CallBackAsynchClass(String ret) throws InterruptedException, ExecutionException {
System.out.println("Callback invoked:"+ret);
returnVal=ret;
}
#Override
public String toString() {
return "CallBackAsynchClass [returnVal=" + returnVal + "]";
}
}
I am expecting "Lock cleared" to be outputted but .get() seems to be holding up the lock.
.thenApply function returns a new instance of CompletableFuture, and it's this instance that you need to use, try using this way instead :
public class CallableAsyncWithCallBack {
public static void main(String[] args) throws InterruptedException {
CompletableFuture<String> compFuture = CompletableFuture.supplyAsync(() -> {
//Compute total
long count = IntStream.range(Integer.MIN_VALUE, Integer.MAX_VALUE).count();
return "" + count;
});
CompletableFuture<String> future = compFuture.thenApply(retVal -> {
try {
return new CallBackAsynchClass(retVal).toString();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ""; });
System.out.println("Main Thread 1");
try {
future.get();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("Lock cleared");
}
}
Hope this helps

#Retryable is not working when calling from a method

Below is my application class. The flow is like the DEToken class from here and from DEToken I call RestConnection where I have the #retryable method.
#SpringBootApplication
#EnableRetry
public class SpringBootTrfficApplication implements CommandLineRunner {
Enter code here
#Autowired
DEToken deToken;
#Autowired
SyncService syncService;
public static void main(String[] args) {
SpringApplication.run(SpringBootTrfficApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
deToken.getToken();
}
}
DEToken class: from getToken I am calling RestConnect where I have the #Retrable method:
#Service
public class DEToken {
private Logger logger = LogManager.getLogger(getClass());
#Autowired
RestConnection restConnection;
#Autowired
private Environment env;
public String accessToken;
public void getToken() {
System.out.println("hello from get token");
//String getJsonPayload = "{\"Query\":{\"RegisterExtensionWithDE\":{\"pid\": \"\",\"providerInsName\":" +
//env.getProperty("provider.ins") + "}}}";
//String str = restConnection.restPost(
// env.getProperty("rest.de.url"), getJsonPayload);
try {
String getJsonPayload =
"{\"Query\":{\"RegisterExtensionWithDE\":{\"pid\": \"\",\"providerInsName\":" +
env.getProperty("provider.ins") + "}}}";
StringBuffer tokenResult =
restConnection.restPost(env.getProperty("rest.de.url"),
getJsonPayload);
System.out.println(tokenResult);
JSONObject xmlJSONObj = XML.toJSONObject(tokenResult.toString());
JSONObject registration = new JSONObject();
if (xmlJSONObj.has("Registration")) {
registration = xmlJSONObj.getJSONObject("Registration");
if (registration.has("accessToken")) {
accessToken = registration.get("accessToken").toString();
}
else
logger.info("no accessToken from DE");
}
else
logger.info("no Registration object from DE");
}
catch (Exception e) {
logger.error("Exception while fetching accesstoken from DE ");
logger.error(e.getMessage());
}
}
}
My REST connection class where I have retryable method:
#Service
public class RestConnection {
private Logger logger = LogManager.getLogger(getClass());
#Autowired
private Environment env;
public void setBaseUrl(String value, String ip) {
//baseUrl = value;
HttpsURLConnection.setDefaultHostnameVerifier(
(hostname, session) -> hostname.equals(ip));
}
/*
* REST post call
*/
#Retryable(value = {IOException.class, ConnectException.class},
maxAttempts = 4,
backoff = #Backoff(5000))
public StringBuffer restPost(String restUrl, String payload) {
StringBuffer sb = new StringBuffer();
HttpURLConnection conn = null;
try {
URL url = new URL(restUrl);
String protocol = url.getProtocol();
if (protocol.toLowerCase().equals("http")) {
conn = (HttpURLConnection)url.openConnection();
}
else if (protocol.toLowerCase().equals("https")) {
//setTrustedCert();
conn = (HttpsURLConnection)url.openConnection();
}
else {
logger.info("Protocol is neither HTTP nor HTTPS");
}
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("version", env.getProperty("de.version"));
conn.setRequestProperty("accessToken", env.getProperty("access.token"));
conn.setRequestProperty("requestHost", env.getProperty("server.de.host"));
conn.setRequestProperty("requestPort", env.getProperty("server.port"));
conn.setRequestProperty("requestProtocol",
env.getProperty("server.de.protocol"));
PrintWriter pout =
new PrintWriter(
new OutputStreamWriter(
conn.getOutputStream(), "UTF-8"),
true);
pout.print(payload);
pout.flush();
pout.close();
InputStream isi = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(isi);
int numCharsRead1;
char[] charArray1 = new char[1024];
while ((numCharsRead1 = isr.read(charArray1)) > 0) {
sb.append(charArray1, 0, numCharsRead1);
}
isr.close();
isi.close();
}
catch (MalformedURLException e) {
logger.error("MalformedURLException in restAccessTokenPOST..." +
e.getMessage());
//e.printStackTrace();
}
catch (IOException e) {
logger.error("IOException in restAccessTokenPOST..." +
e.getMessage());
e.printStackTrace();
}
catch (Exception e) {
logger.error("Exception in restAccessTokenPOST..." +
e.getMessage());
e.printStackTrace();
}
finally {
if (null != conn)
conn.disconnect();
}
return sb;
}
#Recover
public String helpHere(ConnectException cause) {
System.out.println("Recovery place! ConnectException");
return "Hello";
}
#Recover
public String helpHere(IOException cause) {
System.out.println("Recovery place! ArithmeticException");
return "Hello";
}
#Recover
public String helpHere(Exception cause) {
System.out.println("Recovery place! Exception");
return "Hello";
}
#Recover
public String helpHere() {
System.out.println("Recovery place! Exception");
return "Hello";
}
#Recover
public String helpHere(Throwable cause) {
System.out.println("Recovery place! Throwable");
return "Hello";
}
}
Considering you see your function restPost() implementation,
#Retryable(value = {IOException.class, ConnectException.class},
maxAttempts = 4,
backoff = #Backoff(5000))
public StringBuffer restPost(String restUrl, String payload) {
try {
// Your code
}
catch(IOException ex){ // These catch block handles the exception
// and nothing to throw to retryable.
}
catch(MalformedURLException ex){ // More catch blocks that you
// define to handle exception.
}
}
Here you handle all of the exceptions that can be a cause to revoke the retry and recover methods.
Note: Recoverable methods only execute when a exception is thrown, not handled by any try-catch block.
Whatever exception is raised by method restPost() is handled by the method try-catch block itself and there are no exceptions that had been rethrow by a catch block.
Now, Spring-Retry is unable to get any exception (because it is handled by the method try-catch block). So, no recovery method will be executed.
Solution: you should remove those catch blocks from the method definition on which you want to perform retry or recover.
Please do the needful and it will work like a charm... :)

Spring Integration: Custom Splitter with Header Enrichment

Is it possible to have an implementation of a message splitter that can return an Iterator AND add custom header information?
For instance if I have the following class
public class CsvFileToIteratorSplitter extends AbstractMessageSplitter {
#Override
protected Object splitMessage(Message<?> message) {
Object payload = message.getPayload();
Assert.isInstanceOf(File.class, payload, "Expected java.io.File in the message payload");
try {
InputStream source = new FileInputStream((File) payload);
BufferedReader reader = new BufferedReader(new InputStreamReader(source));
String header = reader.lines().findFirst().orElse(null);
return MessageBuilder.withPayload(reader.lines().iterator())
.setHeaderIfAbsent("HEADER", header)
.build();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
Then I can add to the header but the payload is actually an instance of Iterator and the split fails
If I modify so that the class is now
public class CsvFileToIteratorSplitter extends AbstractMessageSplitter {
#Override
protected Object splitMessage(Message<?> message) {
log.debug("{}", message.toString());
Object payload = message.getPayload();
Assert.isInstanceOf(File.class, payload, "Expected java.io.File in the message payload");
try {
InputStream source = new FileInputStream((File) payload);
BufferedReader reader = new BufferedReader(new InputStreamReader(source));
return reader.lines().iterator();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
The split works but I lose the header info.
Is there any way to have a functioning split with the ability to add to the header?
You should return an Iterator<MessageBuilder<String>> ...
#SpringBootApplication
public class So44604817Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(So44604817Application.class, args);
context.getBean("in", MessageChannel.class).send(new GenericMessage<>(new File("/tmp/foo.txt")));
context.close();
}
#Bean
#Splitter(inputChannel = "in")
public MySplitter splitter() {
MySplitter splitter = new MySplitter();
splitter.setOutputChannelName("out");
return splitter;
}
#Bean
public MessageChannel out() {
return new MessageChannel() {
#Override
public boolean send(Message<?> message) {
return send(message, -1);
}
#Override
public boolean send(Message<?> message, long timeout) {
System.out.println(message);
return true;
}
};
}
public static class MySplitter extends AbstractMessageSplitter {
#SuppressWarnings("resource")
#Override
protected Object splitMessage(Message<?> message) {
Object payload = message.getPayload();
Assert.isInstanceOf(File.class, payload, "Expected java.io.File in the message payload");
try {
InputStream source = new FileInputStream((File) payload);
final BufferedReader reader = new BufferedReader(new InputStreamReader(source));
final String header = reader.lines().findFirst().orElse(null);
final Iterator<String> iterator = reader.lines().iterator();
Iterator<MessageBuilder<String>> builderIterator = new Iterator<MessageBuilder<String>>() {
private String next;
#Override
public boolean hasNext() {
if (this.next != null) { // handle multiple hasNext() calls.
return true;
}
if (!iterator.hasNext()) {
try {
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
return false;
}
else {
this.next = iterator.next();
// Handle empty last line
if (next.length() == 0 && !iterator.hasNext()) {
try {
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
return false;
}
return true;
}
}
#Override
public MessageBuilder<String> next() {
String line = this.next;
this.next = null;
return MessageBuilder
.withPayload(line).setHeaderIfAbsent("HEADER", header);
}
};
return builderIterator;
}
catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
}
Note that your skip(1) is incorrect, since the first line has already been consumed from the reader.
With file:
FOO,BAR
foo,bar
baz.qux
result:
GenericMessage [payload=foo,bar, headers={sequenceNumber=1, HEADER=FOO,BAR, correlationId=42ce2e1f-5337-1f75-d4fe-0d7f366f76f1, id=94e98261-fd49-b4d0-f6a0-3181b27f145b, sequenceSize=0, timestamp=1497713691192}]
GenericMessage [payload=baz.qux, headers={sequenceNumber=2, HEADER=FOO,BAR, correlationId=42ce2e1f-5337-1f75-d4fe-0d7f366f76f1, id=c0b1edd6-adb9-3857-cb7c-70f603f376bc, sequenceSize=0, timestamp=1497713691192}]
JIRA Issue INT-4297 to add this functionality to FileSplitter.

Using Java Stream API in already multi-threaded environment

My application has its own thread pool(myThreadPool) and I am assigning one of its threads(Producer) to read a file via java stream API. But in runtime stream is lost somewhere and never reaches the print method. But when I run the stream in single threaded environment it works. Does it happen because java stream Api uses its own thread pool underneath or is this conceptually wrong?
public class Processor {
public void process() {
ExecutorService myThreadPool = Executors.newFixedThreadPool(3);
myThreadPool.execute(new Producer());
}
private class Producer implements Runnable{
#Override
public void run() {
try (Stream<String> lines = Files.lines(Paths.get("Path"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I don't know what you have happen. but I can give you an advice (maybe your program exited and Producer is not terminated). copy this code and see what wrong of your code.
public class Processor {
public void process() {
ExecutorService myThreadPool = Executors.newFixedThreadPool(3);
try {
myThreadPool.execute(new Producer());
Thread.currentThread().join();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private class Producer implements Runnable {
#Override
public void run() {
try (Stream<String> lines = Files.lines(Paths.get("Path"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
OR
public class Processor {
public void process() {
ExecutorService myThreadPool = Executors.newFixedThreadPool(3);
try {
myThreadPool.submit(() -> {
new Producer().run();
return null;
}).get();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private class Producer implements Runnable {
#Override
public void run() {
try (Stream<String> lines = Files.lines(Paths.get("Path"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Resources