Finagle connect to a service and not the host - url

I have a server that hosts many services.
In a scala application, I need to query one of its services : service1/api/endpoint1
The problem I'm facing, is that Http.client.newService expects a host with a port, so in my case
val client: Service[Request, Response] = Http.client
.withRetryBudget(budget)
.withMaxResponseSize(StorageUnit.fromMegabytes(1900))
.withRetryBackoff(Backoff.const(10.seconds))
.newService("myHost:9999")
When posting a request
val req = RequestBuilder
.post("/service/api/endpoint1")
.body(jsonReq)
.request
val request: Future[Response] = client(req)
val response = Await.result[Response](request, Duration.fromMinutes(4))
I got the error
An existing connection was forcibly closed by the remote host at remote address myhost:9999
because myhost:9999 doesn't allow direct connections, one can only connect to one of it's services, myhost:9999/service1 or so..
Is there a way to achieve this ? i.e to create the httpclient with the whole url myHost:9999/service1 ?

Related

How to get the remote host from a rsocket

I now receive an rsocket connection in my spring project, and then I want to get its remote address and port, how should I get it?Similar to using socket.getRemoteSocketAddress() to get the remote address of the socket.
#ConnectMapping
public void connectMapping(RSocketRequester requester) {
// there is a resockt connect, how can i get the remote host from it
RSocket rSocket = requester.rsocket();
// TODO
logger.info("host port");
}
Unfortunately, I think even if you grab the RSocketRequester in #ConnectMapping or #MessageMapping method it is an internal detail. io.rsocket.core.RSocketRequester via RequesterResponderSupport holds the DuplexConnection which represents a connection over tcp, web socket or in-process. It is not exposed via a public API.
This is a worthy request but you will need to file a feature request to get this added unless I'm missing something obvious.
It isn't clear that there is a hook in https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/api/org/springframework/boot/rsocket/server/RSocketServerCustomizer.html to let you see the DuplexConnection (tcp or web socket etc) as it's established.

Jenkins JNLP port exposes internal ip

We have configured our Jenkins server to use a fixed port and JNLP 4.
Our info sec team has flagged that if one were to open a web browser pointing at the JNLP port, the internal properties below are listed which includes the internal ip of the Jenkins server.
Jenkins-Agent-Protocols:
Jenkins-Version:
Jenkins-Session:
Client:
Server:
Remoting-Minimum-Version:
Is this information necessary? Is this something which can be suppressed?
From the source: https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/TcpSlaveAgentListener.java
It looks like there is no mechanism to turn it off, and according to the comments, it seems to be only for testing:
String header = new String(head, Charsets.US_ASCII);
if (header.startsWith("GET ")) {
// this looks like an HTTP client
respondHello(header,s);
return;
}
// otherwise assume this is AgentProtocol and start from the beginning
(...)
/**
* Respond to HTTP request with simple diagnostics.
* Primarily used to test the low-level connectivity.
*/
private void respondHello(String header, Socket s) throws IOException {
(...)
If infosec requires you to turn this off, you might need to open a support ticket with cloudbees.

Error passing InputStream through multiple Jersey-Client requests

I’m using jersey-client v1.18.1
I need to make 2 sequential requests where the 1st request has an InputStream and then must pass that same InputStream along to the 2nd request (eg. sort of like a proxy). The 2nd request will then write the InputStream to disk and send back to the 1st request the fully qualified path to the location on disk where the 2nd request wrote the file.
The following code-snippet outlines what I have tried, but cannot get to work properly. I’m currently receiving the error:
"com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class org.seleniumhq.jetty9.server.HttpInputOverHTTP, and MIME media type, application/octet-stream, was not found”
I believe I have all the proper Maven dependencies in my project for the MIME and message body writers.
1st Request originating on Host 1 going to Host 2
Client client = Client.create();
client.resource(uri_for_request_1)
client.path(“request_1_servlet");
client.queryParam(“uri_for_request_2", uri_for_request_2);
client.queryParam("targetFilename", targetFilename);
ClientResponse response = client.accept(MediaType.APPLICATION_JSON).entity(inputStream).post(ClientResponse.class);
2nd Request originating on Host 2 going to Host 3
Client client = Client.create();
client.resource(request.getParamater(“uri_for_request_2"))
client.path(“request_2_servlet");
client.queryParam("targetFilename", request.getParamater(“targetFilename");
ClientResponse response = client.accept(MediaType.APPLICATION_JSON).entity(request.getInputStream()).post(ClientResponse.class);
Host 3
Writes InputStream to file and sends back to Host 2 fully qualified path.
Host 2
Sends back to Host 1 fully qualified path.
Variations I’ve tried on post calls:
client.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_OCTET_STREAM).entity(inputStream).post(ClientResponse.class);
client.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_OCTET_STREAM).post(ClientResponse.class, inputStream);
I can confirm the 1st request is being made on Host 1 and reaches Host 2. It is the 2nd request on Host 2 that fails during the post() call.

Jersey Client opens too many Connections

i run in some problems with my jersey rest api and a client.
This is how im using the methods on a server side:
#POST
#Path("/seed")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response addSeed(Seed seed) throws InterruptedException {
if (!Validator.isValidSeed(seed)) {
return Response.status(400).entity("{\"message\":\"Please verify your JSON!\", \"stat\":\"failed\"}")
.build();
}
save(seed);
return Response.status(200).build();
}
If i run a Jersey client in a while(true) loop, there are connections open and won't close. So im running into a problem i have a lot of connections open and my network crashes. So i can't use my server any more. After the connections are closed i can connect to the server.
This is a client:
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(getBaseURI()).path("api/seed");
while (true) {
ClientResponse cr = service.header("Content-Type", "application/json").post(ClientResponse.class, seed);
System.out.println(cr);
cr.close();
My Questions are:
What can i do on the server side, to prevent clients open a new connection?
How can i specify a max number of connections?
And how should i implement the jersey client to reuse open connection?
I don't know of a way to limit Jersey resources at the web-app level. If you upgrade to GlassFish EE, you can make your resources EJBs #Stateless #StatelessDeployment(maxInstances=16)
The pile up of connections could be because of Keep-Alive settings. In Tomcat 6 there are two you can tune your connector with:
maxKeepAliveRequests, which defaults to 100. It's the maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests.
keepAliveTimeout, which defaults to connectionTimeout which defaults to 60k ms. It it the number of milliseconds this Connector will wait for another HTTP request before closing the connection.

mina server response port different from port incoming messages

I set up a server that receives messages over port xxx, but I want to respond to port yyy.
Is there a simple way to achieve this?
My server:
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.setHandler(new MessageHandler());
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", new protocolCodecFilter(codecFactory));
acceptor.getSessionConfig().setReadBufferSize(bufferSize);
acceptor.bind(new InetSocketAddress(port));
The encode method of my encoder:
public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
byte[] writeBytes = (byte[]) message;
IoBuffer buffer = IoBuffer.allocate(writeBytes.length).setAutoExpand(false);
buffer.put(writeBytes);
buffer.flip();
out.write(buffer);
writeMessage(session,writeBytes);
}
The msessage should be written to a different port. How do I achieve this?
If you want to response message using different tcp port, you must make another other tcp connection first, which means you have two servers and tow clients.
request
client1---------->server1
reponse
server2---------->client2

Resources