Correctly shutting down a websocket handler
by Robin Anil
When a client disconnects, I see that onClose is not being fired. The only
way this seems to be firing if client sents a close frame.
Is there any way to detect disconnection and immediately close all the
opened resources.
Robin
Robin Anil | Software Engineer
1 year, 3 months
Streaming a ZIP file
by Hicks, Matt
I'm trying to create ZIP files on-demand from the server and stream them
back to the browser, but I'm not sure the proper way to do this. The only
way I can think of is to use a `ZipOutputStream`, but that would be a
blocking operation. Is there a better way to do this?
7 years, 3 months
Fwd: Issue with Java 9 (Jigsaw) when using Undertow
by Tester
Hi,
I'm using the Spring Boot starter for Undertow. The dependencies which are
pulled in are:
org.springframework.boot:spring-boot-starter-undertow:jar:2.0.0.M3:compile
| +- io.undertow:undertow-core:jar:1.4.18.Final:compile
| | +- org.jboss.xnio:xnio-api:jar:3.3.8.Final:compile
| | \- org.jboss.xnio:xnio-nio:jar:3.3.8.Final:runtime
| +- io.undertow:undertow-servlet:jar:1.4.18.Final:compile
| | \- org.jboss.spec.javax.annotation:jboss-annotations-
api_1.2_spec:jar:1.0.0.Final:compile
| +- io.undertow:undertow-websockets-jsr:jar:1.4.18.Final:compile
| | \- org.jboss.spec.javax.websocket:jboss-websocket-api_
1.1_spec:jar:1.1.0.Final:compile
| +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
| \- org.glassfish:javax.el:jar:3.0.0:compile
Now, when I run the application through Java 9 (Release candidate) and I
have a module-info.java (Jigsaw), then I get the following error:
Error occurred during initialization of boot layer
java.lang.module.FindException: Unable to derive module descriptor for
C:\Users\xxxxx\.m2\repository\org\jboss\spec\javax\
annotation\jboss-annotations-api_1.2_spec\1.0.0.Final\
jboss-annotations-api_1.2_spec-1.0.0.Final.jar
Caused by: java.lang.IllegalArgumentException: jboss.annotations.api.1.2.spec:
Invalid module name: '1' is not a Java identifier
It seems there is an issue with the determination of the naming of the
automatic module. I expect to have the same issue
for jboss-websocket-api_1.1_spec.
The name of the jar file isn't aligned on the algorithm defined under (
http://download.java.net/java/jigsaw/docs/api/java/
lang/module/ModuleFinder.html).
Is anyone aware of this issue? Is this something that can be resolved?
7 years, 4 months
Re: [undertow-dev] Using UndertowClient from one server to call another server
by Stuart Douglas
That would be great. This is tested in the test suite so I am not sure why
it is not working for you.
Stuart
On 29 Aug. 2017 12:59 pm, "Steve Hu" <stevehu(a)gmail.com> wrote:
Yes. It is another Undertow server with HTTP 2.0 enabled. I can build a
repo with two servers to reproduce the issue if it is necessary.
Thanks,
Steve
On Mon, Aug 28, 2017 at 10:43 PM, Stuart Douglas <sdouglas(a)redhat.com>
wrote:
> What is the endpoint that you are trying to connect to? Is it another
> Undertow server?
>
> Stuart
>
> On Tue, Aug 29, 2017 at 12:17 PM, Steve Hu <stevehu(a)gmail.com> wrote:
> > Hi Stuart,
> >
> > Thanks for the quick reply. I have opened an issue
> > https://issues.jboss.org/browse/UNDERTOW-1170
> >
> > Also, I have tried your workaround with h2c-prior:// but got the
> following
> > error in the callback.
> >
> > java.nio.channels.ClosedChannelException
> > at
> > io.undertow.protocols.http2.Http2Channel.createStream(Http2C
> hannel.java:827)
> > at
> > io.undertow.client.http2.Http2ClientConnection.sendRequest(H
> ttp2ClientConnection.java:195)
> > at
> > com.networknt.apic.handler.DataGetHandler.handleRequest(Data
> GetHandler.java:57)
> >
> >
> > On Mon, Aug 28, 2017 at 9:50 PM, Stuart Douglas <sdouglas(a)redhat.com>
> wrote:
> >>
> >> This looks like a bug in the client with regards to how it handles
> >> HTTP upgrade. If the second request is added before the initial
> >> upgrade request is fully processed you can get this error.
> >>
> >> If you file a JIRA I will look into it. For now a possible workaround
> >> would be to use prior knowledge rather than upgrade (by using a URL of
> >> the form h2c-prior://target:p8080/whatever).
> >>
> >> Stuart
> >>
> >> On Tue, Aug 29, 2017 at 11:25 AM, Steve Hu <stevehu(a)gmail.com> wrote:
> >> > Hi,
> >> >
> >> > I am trying to use UndertowClient to call another service in the
> current
> >> > service handleRequest using HTTP 2.0. If I have concurrent requests to
> >> > the
> >> > current service, then I will get the following error.
> >> >
> >> > java.io.IOException: UT001033: Invalid connection state
> >> > at
> >> >
> >> > io.undertow.client.http.HttpClientConnection.sendRequest(Htt
> pClientConnection.java:336)
> >> >
> >> > Since HTTP 2.0 connection is multiplex, so I use instance variables
> for
> >> > UndertowClient instance and ClientConnection instance and don't close
> >> > the
> >> > connection for each call.
> >> >
> >> > My question is how many requests can go through the same connection?
> Is
> >> > the
> >> > Invalid connection state caused by too many requests in the same
> >> > connection?
> >> > If yes, I can use a connection pool just like the HTTP 1.1. Also, is
> it
> >> > possible that the server will close the connection if it is idle for a
> >> > period of time?
> >> >
> >> > Here is the handler code for reference.
> >> >
> >> > public class DataGetHandler implements HttpHandler {
> >> > UndertowClient client = UndertowClient.getInstance();
> >> > ClientConnection connection;
> >> >
> >> > @Override
> >> > public void handleRequest(HttpServerExchange exchange) throws
> >> > Exception
> >> > {
> >> > List<String> list = new ArrayList<>();
> >> > final CountDownLatch latch = new CountDownLatch(1);
> >> > if(connection == null) {
> >> > try {
> >> > connection = client.connect(new URI(apidHost),
> >> > Http2Client.WORKER, Http2Client.SSL, Http2Client.POOL, enableHttp2 ?
> >> > OptionMap.create(UndertowOptions.ENABLE_HTTP2, true):
> >> > OptionMap.EMPTY).get();
> >> > } catch (Exception e) {
> >> > logger.error("Exeption:", e);
> >> > throw new ClientException(e);
> >> > }
> >> > }
> >> > final AtomicReference<ClientResponse> reference = new
> >> > AtomicReference<>();
> >> > try {
> >> > ClientRequest request = new
> >> > ClientRequest().setMethod(Methods.GET).setPath(apidPath);
> >> > connection.sendRequest(request,
> >> > client.createClientCallback(reference, latch));
> >> > latch.await();
> >> > int statusCode = reference.get().getResponseCode();
> >> > if(statusCode >= 300){
> >> > throw new Exception("Failed to call API D: " +
> >> > statusCode);
> >> > }
> >> > List<String> apidList =
> >> >
> >> > Config.getInstance().getMapper().readValue(reference.get().
> getAttachment(Http2Client.RESPONSE_BODY),
> >> > new TypeReference<List<String>>(){});
> >> > list.addAll(apidList);
> >> > } catch (Exception e) {
> >> > logger.error("Exception:", e);
> >> > throw new ClientException(e);
> >> > }
> >> > list.add("API C: Message 1");
> >> > list.add("API C: Message 2");
> >> >
> >> >
> >> > exchange.getResponseSender().send(Config.getInstance().getMa
> pper().writeValueAsString(list));
> >> > }
> >> > }
> >> >
> >> >
> >> > _______________________________________________
> >> > undertow-dev mailing list
> >> > undertow-dev(a)lists.jboss.org
> >> > https://lists.jboss.org/mailman/listinfo/undertow-dev
> >
> >
>
7 years, 4 months
Using UndertowClient from one server to call another server
by Steve Hu
Hi,
I am trying to use UndertowClient to call another service in the current
service handleRequest using HTTP 2.0. If I have concurrent requests to the
current service, then I will get the following error.
java.io.IOException: UT001033: Invalid connection state
at
io.undertow.client.http.HttpClientConnection.sendRequest(HttpClientConnection.java:336)
Since HTTP 2.0 connection is multiplex, so I use instance variables for
UndertowClient instance and ClientConnection instance and don't close the
connection for each call.
My question is how many requests can go through the same connection? Is the
Invalid connection state caused by too many requests in the same
connection? If yes, I can use a connection pool just like the HTTP 1.1.
Also, is it possible that the server will close the connection if it is
idle for a period of time?
Here is the handler code for reference.
public class DataGetHandler implements HttpHandler {
UndertowClient client = UndertowClient.getInstance();
ClientConnection connection;
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception
{
List<String> list = new ArrayList<>();
final CountDownLatch latch = new CountDownLatch(1);
if(connection == null) {
try {
connection = client.connect(new URI(apidHost),
Http2Client.WORKER, Http2Client.SSL, Http2Client.POOL, enableHttp2 ?
OptionMap.create(UndertowOptions.ENABLE_HTTP2, true):
OptionMap.EMPTY).get();
} catch (Exception e) {
logger.error("Exeption:", e);
throw new ClientException(e);
}
}
final AtomicReference<ClientResponse> reference = new
AtomicReference<>();
try {
ClientRequest request = new
ClientRequest().setMethod(Methods.GET).setPath(apidPath);
connection.sendRequest(request,
client.createClientCallback(reference, latch));
latch.await();
int statusCode = reference.get().getResponseCode();
if(statusCode >= 300){
throw new Exception("Failed to call API D: " + statusCode);
}
List<String> apidList =
Config.getInstance().getMapper().readValue(reference.get().getAttachment(Http2Client.RESPONSE_BODY),
new TypeReference<List<String>>(){});
list.addAll(apidList);
} catch (Exception e) {
logger.error("Exception:", e);
throw new ClientException(e);
}
list.add("API C: Message 1");
list.add("API C: Message 2");
exchange.getResponseSender().send(Config.getInstance().getMapper().writeValueAsString(list));
}
}
7 years, 4 months
Writing tests for HTTP handlers
by Michael Hixson
Hello,
I want to write junit tests for my application's HttpHandlers and I'm
wondering what the best way to simulate a request/response exchange
is. How do other people go about this?
My first thought was that I want to somehow:
1) Build up a valid HttpServerExchange object to represent my incoming
request (likely the HTTP method, request URI, HTTP headers, and
request entity/body would vary from test to test)
2) Instantiate my HttpHandler directly, and invoke its handleRequest
method directly
3) Obtain a CompletableFuture that will complete when the exchange
completes (possibly by adding an
io.undertow.server.ExchangeCompletionListener to my exchange)
4) Verify the contents of the response (possibly by examining the
HttpServerExchange object and by using an
io.undertow.conduits.StoredResponseStreamSinkConduit to record the
response entity)
This would all happen without creating an Undertow instance or binding
to any ports.
I started writing my own mock request/response library classes and
they're getting complicated enough that I'd rather reuse someone
else's work here if possible.
Maybe I'm going down the wrong path... I could create an Undertow
server instance and use something like a Jersey client to make actual
HTTP requests. Is that what other people do in their tests?
-Michael
7 years, 4 months