How do we connect Spring WebClient to a Unix Domain Socket? - spring

Spring's WebClient underlyingly uses Netty which access to Unix domain sockets. I am trying to make it access /var/run/docker.sock so that I can perform operations using the API as I need /services which is not supported by the docker-java library.
My current workaround is to create a socat container that exposes the Docker socket to TCP within an internal network which in turn allows me to use WebClient's HTTP connections.
Though come to think of it, having this workaround gives one benefit of not needing to put a larger Java application on the manager node.
However, I am still curious how to connect to the unix domain docket.

You can create a Netty HttpClient following their documentation regarding Unix Domain Sockets here.
import io.netty.channel.unix.DomainSocketAddress;
import reactor.netty.http.client.HttpClient;
HttpClient client = HttpClient.create()
.remoteAddress(() -> new DomainSocketAddress("/var/run/docker.sock"));
Then you can tell WebClient to use this HttpClient like this.
WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(client))
.build();

You can expose the docker daemon over TCP and use the REST API.

Related

How to make a socket server that listens for client connections and opens a socket once an Endpoint is called in Spring?

I have an application that opens a "HttpURLConnection" to a printer. The printer is listening for socket connection and makes a connection when a new TCP socket connection is opened on the Application side (In this case through a new "HttpURLConnection"). Now, I want to mock this printer.
In the Application an Http call is made to the printer server and a socket connection is established between the Application and the server. How do I mock this printer as a spring boot application.
Sounds like you need to take a look into Spring Test Framework and especially its part about a Web: https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/testing.html#spring-mvc-test-client
I would really investigate a possibility to interact via a RestTemplate instead of direct HttpURLConnection and then use that MockRestServiceServer for mocking requests and responses.
Another way is to use a #SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) and implement controller with appropriate mappings and possible return results. This way you would be able to use the mentioned HttpURLConnection to connect to randomly allocated port for HTTP server and perform requests as in production.

RestTemplate (or WebClient) per destination socket and connect timeouts

Is there a way with either client (RestTemplate or the newer WebClient) to set per destination socket or connect timeouts? For example in an API aggregation web service, where I talk to several different services/hosts, it's often desirable to have different socket timeouts based on if the services are internal or external/3rd party. The only solution I know of (with RestTemplate, I haven't used WebClient) is to instantiate a separate RestTemplate with a different socket timeout/connect timeout (and do this for each host that requires a different timeout).
This is fairly annoying because the amount of setup code required for a RestTemplate configured with HttpComponents is non-trivial, and having to add #Qualifier at every use of RestTemplate injection is also non-ideal. Further, the fact that HttpComponents allows for max total connections and max routes to host implies that one RestTemplate talking to all outbound traffic is the expected usage.

Jetty websocket client connect to Stomp.js topic channel

I have written a Spring Websocket server which is assessible from a browser via Stomp.js. I am now attempting to implement a Java client in order to connect my server to a secondary system. I am able to connect to the server using the following code
String destUri = "ws://localhost:8080/sample";
WebSocketClient client = new WebSocketClient();
SimpleEchoSocket socket = new SimpleEchoSocket();
try {
client.start();
URI echoUri = new URI(destUri);
ClientUpgradeRequest request = new ClientUpgradeRequest();
client.connect(socket, echoUri, request);
System.out.printf("Connecting to : %s%n", echoUri);
socket.awaitClose(5, TimeUnit.SECONDS);
} catch (Throwable t) {
t.printStackTrace();
}
The connection is opened, and now I would like to connect to my topic /price-stream. This is achieved by stomp.js :
stompClient.subscribe('/topic/pricechannel1', renderPrice);
what is the equivalent subscribe method for my Jetty websocket client? I cant find anything in the documentation I have found on the net.
Additional info:
I am trying to implement the stockticker example found here into another project. I can connect to the server through the provided Stomp.js interface in a web browser. Now I am attempting to create a Java client for use within a Swing GUI using Jetty websocket-client to connect.
I need to connect to the price stream, but it seems I am missing some kind of configuration request to latch on as a destination for the topic
In general, plain websocket clients (as the one provided by Jetty) support the websocket standard. STOMP is a protocol that sits on top of that transport.
Here, you'd need to implement your own STOMP client or interface an existing one with the websocket client you're using.
Spring 4.2 (to be published soon) includes a new STOMP client for this particular use case. See the reference documentation of 4.2.RC2.

Spring Integration. Unknown host and tcp-connection-factory

I'm implementing the TCP client using the Spring Integration.
The requirements are:
1. Through the UDP connection (from somewhere) receive the ip or host address of the TCP server.
2. Open TCP connection to the server, to the destination host from previous step and send some business data to this server.
I use the Spring Integration framework, version "2.2.0.RELEASE", and the problem is that in the default configuration of the tcp-connection-factory the host attribute should be "hardcoded" in xml. For example:
<ip:tcp-connection-factory id="client" type="client" host="localhost" port="1234" single-use="true"/>
The question is how to avoid the static definition of the destination host in application context, and be able to 'lazy' initialise the tcp-connection-factory when the destination host will be known.
I know that this flow could be easily implemented by the standard Network APIs of Java, and the question is specific about the Spring-Integration API
At this time, the configuration is static.
You could however use a similar technique to that used in the dynamic ftp sample which configures ftp outbound adapters at runtime.
As far as <int-ip:tcp-connection-factory> provides some instance of AbstractConnectionFactory. And from other side <int-ip:tcp-outbound-channel-adapter> applies that instance via connection-factory, so, there is no stops to implement your own RoutingConnectionFactory.
The implementation may rely on some value from ThreadLocal. The idea is here:
https://github.com/spring-projects/spring-amqp/blob/master/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/AbstractRoutingConnectionFactory.java,
https://github.com/spring-projects/spring-framework/blob/master/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java
It's not currently possible/easy - even if you customize or extend the class for tcp-connection-factory to be able to connect to changing hosts. There is an open new feature request in JIRA to provide this functionality.

Solr running on Https - SolrJ Connection issue

Am running Solr in Https(8443) port on top of tomcat, How can i access that solr using solrj client, I can see only CommonsHttpSolrServer is availble,
Please suggest is there any way to access the https port enabled solr using SolrJ?.
Solrj internally uses Apache Http Client. When using CommonsHttpSolrServer it will create one & use it, if you are not providing it with one.
In this case since you need support for SSL you could provide your own SSL configured HttpClient to CommonsHttpSolrServer constructor. Check its API that accepts HttpClient.
CommonsHttpSolrServer(String solrServerUrl, HttpClient sslHttpClient, ...
You can see the following guide, on how to create SSL enabled http client SSL Guide.
This should help.

Resources