TCP socket client using Spring Boot Web - spring

I'm developing a web application using Spring Boot Web and I want to communicate with a TCP socket server using IP and Port (connect, send, receive and disconnect).
I'm new to Spring Boot and I searched many days in the internet without any working result and the Websocket solution will not work in this case.
UPDATE (please confirm)
I think that I can use the standard java.io.* and java.net.* in Spring Boot Web juste like any other Java Program:
try {
try (Socket clientSocket = new Socket(IP, PORT);
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader br = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()))) {
System.out.println("Connected to server");
String str = "test";
out.write(str);
out.flush();
char[] cbuf = new char[size];
br.read(cbuf, 0, size);
System.out.println(cbuf);
}
} catch (IOException ex) {
ex.printStackTrace();
}

This is my own version of a simple tcp client developed for SpringBoot.
First, you have to open the connection with the openConnection() method. Then, you can send messages with sendMessage() method and receive messages with takeMessage() method.
#Service("socketClient")
public class SocketClient {
#Value("brain.connection.port")
int tcpPort;
#Value("brain.connection.ip")
String ipConnection;
private Socket clientSocket;
private DataOutputStream outToTCP;
private BufferedReader inFromTCP;
private PriorityBlockingQueue<String> incomingMessages = new PriorityBlockingQueue<>();
private PriorityBlockingQueue<String> outcomingMessages = new PriorityBlockingQueue<>();
private final Logger log = LoggerFactory.getLogger(this.getClass());
private Thread sendDataToTCP = new Thread(){
public void run(){
String sentence = "";
log.info("Starting Backend -> TCP communication thread");
while(true){
try {
sentence = incomingMessages.take();
outToTCP.writeBytes(sentence + '\n');
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
private Thread getDataFromTCP = new Thread(){
public void run(){
log.info("Starting TCP -> Backend communication thread");
while(true){
String response = "";
try {
response = inFromTCP.readLine();
if (response == null)
break;
outcomingMessages.put(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
public void openConnection(){
try {
this.clientSocket = new Socket(ipConnection, tcpPort);
outToTCP = new DataOutputStream(clientSocket.getOutputStream());
inFromTCP = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
getDataFromTCP.start();
sendDataToTCP.start();
} catch (IOException e) {
e.printStackTrace();
}
}
//Send messages to Socket.
public void sendMessage(String message) throws InterruptedException {
incomingMessages.put(message);
}
//Take Message from Socket
public String takeMessage() throws InterruptedException {
return outcomingMessages.take();
}
}

Related

#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... :)

How to receive and reply on Spring

I'm trying to deploy a RPC (request/reply pattern) and I'm using RabbitMQ and Spring in the server side because I need dynamic consumers. I can configurate dynamic consumers with SimpleMessageListenerContainer but i don't know how to reply my message.
Here is my class configuration:
#Configuration
public class dynamicConsumerConfig {
private static Properties prop = new Properties();
public static void setPropValues() throws IOException {
File configFile = new File("src/main/resources/config.properties");
InputStream inStream = new FileInputStream(configFile.getAbsolutePath());
prop.load(inStream);
}
#Bean
public Queue slowQueue() {
return new Queue("slowQueue");
}
#Bean
public Queue fastQueue() {
return new Queue("fastQueue");
}
#Bean
public DirectExchange exchange1() {
return new DirectExchange("pdfqueues");
}
#Bean
public Binding slowBind(DirectExchange exchange, Queue slowQueue) {
return BindingBuilder.bind(slowQueue)
.to(exchange)
.with("slow");
}
#Bean
public Binding fastBind(DirectExchange exchange, Queue fastQueue) {
return BindingBuilder.bind(fastQueue)
.to(exchange)
.with("fast");
}
#Bean
public ConnectionFactory connect() throws IOException {
setPropValues();
CachingConnectionFactory connection = new CachingConnectionFactory();
connection.setHost(prop.getProperty("HOST"));
connection.setUsername(prop.getProperty("USER"));
connection.setPassword(prop.getProperty("PASS"));
connection.setPort(Integer.parseInt(prop.getProperty("PORT")));
return connection;
}
#Bean
public SimpleMessageListenerContainer container1(ConnectionFactory connection) throws IOException {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
setPropValues();
container.setConnectionFactory(connection);
container.setQueueNames("slowQueue");
container.setMessageListener(firstListener());
container.setMaxConcurrentConsumers(8);
container.setConcurrentConsumers(1);
container.setConsecutiveActiveTrigger(1);
container.setConsecutiveIdleTrigger(1);
container.setTxSize(1);
container.setPrefetchCount(1);
return container;
}
#Bean
public MessageListener firstListener()
{
return new MessageListener() {
#Override
public void onMessage(Message message) {
PdfBoxService pdfboxservice = new PdfBoxService(prop.getProperty("tmpPath"),prop.getProperty("imagicPath"),prop.getProperty("resources"),
prop.getProperty("tessdata"),prop.getProperty("languages"));
String picture = new String(message.getBody(), StandardCharsets.UTF_8);
List<ImagePair> lip = null;
try {
lip = new ArrayList<ImagePair>();
lip.add(new ImagePair("JPG", picture));
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ByteArrayOutputStream output= pdfboxservice.ImgToPdf(lip, false, false, false, 1, 1);
} catch (IOException | InterruptedException | TransformerException | BadFieldValueException
| TesseractException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
In the fuction firstListener() i get the message. In this case is a picture. The picture is converted from JPG to PDF. The PDF is stored in outputvariable.
I need to reply this output in other queue but i don't have tools for do it.
I think that my code is a bad pattern but I don't know how to do a RPC pattern with dynamic consumers using SimpleMessageListenerContainer.
Use a MessageListenerAdapter with a POJO method that returns a result instead of implementing MessageListener yourself.
Starting with version 2.0, a convenient FunctionalInterface has been provided:
#FunctionalInterface
public interface ReplyingMessageListener<T, R> {
R handleMessage(T t);
}
This facilitates convenient configuration of the adapter using Java 8 lamdas:
new MessageListenerAdapter((ReplyingMessageListener<String, String>) data -> {
...
return result;
}));

Netty WebScoketClientHandshaker not working

i have a question. who can help me? it'll be very appreciate. i wanna make websocketclient but my code blocked at handShaker.handshake(ch).syncUninterruptibly();...
websocket server is working well becuase i've test it using JS.only netty client not working..
belows is my code
public void Start() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try{
Bootstrap b = new Bootstrap();
URI uri = new URI(url);
WebSocketClientHandshaker handShaker = WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, false, null);
WebSocketClientHandler handler = new WebSocketClientHandler(handShaker, actionHandlers);
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpClientCodec());
pipeline.addLast(new HttpObjectAggregator(8192));
pipeline.addLast(handler);
}
});
ch = b.connect(uri.getHost(), uri.getPort()).sync().channel();
//handler.handShakeFuture().sync();
handShaker.handshake(ch).syncUninterruptibly();
ch.closeFuture().awaitUninterruptibly();
}catch(Exception e) {
e.printStackTrace();
}
}

Receive MapMessage by Consumer shows nothing

Hello i am facing a strange(for me ) problemm with MapMessage in ActiveMQ. My code produces no error but it shows nothing.
Producer code:
public void sendMapMessageTopic(String topicName) throws Exception {
try {
initConnectionTopic(topicName);
mapMessage = session.createMapMessage();
mapMessage.setIntProperty("Age", 24);
mapMessage.setStringProperty("Full Name", "Konstantinos Drakonakis");
mapMessage.setStringProperty("Height", "178cm");
List<String> data = new ArrayList<String>();
data.add("Company");
data.add("Project");
mapMessage.setObject("data", data);
Map<String, Object> specs = new HashMap<String, Object>();
specs.put("data", data);
mapMessage.setObject("specs", specs);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(mapMessage);
} catch (Exception e) {
System.out.println("Exception while sending map message to the queue" + e.getMessage());
throw e;
} finally {
if (connection != null) {
connection.close();
if (session != null) {
session.close();
}
}
}
}
Consumer code:
public void startReceivingMapMessageTopic(String topicName) throws Exception {
try {
//get connection factory
connectionFactory = new ActiveMQConnectionFactory(username, password, brokerUrl);
//create a connection
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//create destination(unless it already exists)
queue = session.createTopic(topicName);
consumer = session.createConsumer(queue);
messageMap = (MapMessage) consumer.receive(1000);
if (messageMap instanceof MapMessage) {
MapMessage m = messageMap;
System.out.println("The contents of MapMessage is: " + m.getStringProperty("Age"));
}
System.in.read();
consumer.close();
connection.close();
session.close();
} catch (Exception e) {
System.out.println("Exception while sending message to the queue" + e.getMessage());
throw e;
}
}
Main method for Producer:
public static void main(String[] args) {
//connect to the default broker url
ActiveMQQueueSender sender = new ActiveMQQueueSender("tcp://localhost:61616", "admin", "admin");
try {
sender.sendMapMessageTopic("Map Message Topic");
} catch (Exception ex) {
System.out.println("Exception during" + ex.getMessage());
}
}
Main method for consumer:
public static void main(String[] args) {
ActiveMQQueueReceiver receiver = new ActiveMQQueueReceiver("tcp://localhost:61616", "admin", "admin");
try {
receiver.startReceivingMapMessageTopic("Map Message Topic");
} catch (Exception ex) {
System.out.println("Exception during receival in main class" + ex.getMessage());
}
}
But still i get nothing. Any ideas?

weblogic.net.http.HttpUnauthorizedException: Proxy or Server Authentication Required

I am trying to connect to a REST API in an application deployed on weblogic 10.3.6. The sample code works fine when run independently (outside weblogic server). But when I deploy the same code it starts giving me this error
Failed to communicate with proxy: proxy.xxx.xxx/xxxx. Will try connection api.forecast.io/443 now.
weblogic.net.http.HttpUnauthorizedException: Proxy or Server Authentication Required
at weblogic.net.http.HttpURLConnection.getAuthInfo(HttpURLConnection.java:297)
at weblogic.net.http.HttpsClient.makeConnectionUsingProxy(HttpsClient.java:440)
at weblogic.net.http.HttpsClient.openServer(HttpsClient.java:351)
at weblogic.net.http.HttpsClient.New(HttpsClient.java:527)
at weblogic.net.http.HttpsURLConnection.connect(HttpsURLConnection.java:239)
Code that we are running is as below
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[] { new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} }, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) { // should never happen
e.printStackTrace();
}
try {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.xxxx.xxxx", xxxx));
URL url = new URL("https://api.forecast.io/forecast/xxxxxxxxx/12.9667,77.5667");
HttpURLConnection conn = (HttpURLConnection)url.openConnection(proxy);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
Our proxy is a company proxy and doesn't have any username/password. We are stuck on this issue for sometime now. Any suggestions/pointers will be really appreciated.

Resources