You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openwebbeans.apache.org by Alexander Fischer <fi...@mailbox.org> on 2020/06/04 13:34:58 UTC

GSOC 2020 progress update

Hello everyone,

in the last month I have spent most of my time getting to know coding
basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
extensions which will be the technological foundation for the server.

Next up will be defining and implementing the HTTP API, which will bring
CDI and Netty together. Feel free to contribute your thoughts on the
matter here on the mailing list or in the respective Jira issue:
https://issues.apache.org/jira/projects/OWB/issues/OWB-1319

@Romain: can you share some ideas, annotations, interfaces for how you
see the API roughly? Any kind of formal requirement-proposal would be
helpful to start with.

Thanks and best regards,
Alexander


Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hi Romain!

Thank you for the extensive answer.  I will first make an example for
how I understood the API, and I'd say we proceed from there. I will
check back on you once that's done.

Best regards,
Alex

On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> Hi Alex,
>
> Nothing is written in the stone but here is how I would approach that:
>
> 1. Write a HTTP server able to call a handler to answer a request - you can
> start by giving a hardcoded handler but in terms of design, ensure you get
> something taking a Request abstracting as input and a Response abstraction
> as output.
> Netty has these abstraction but we don't want to depend on netty so you
> should duplicate it making it even more user friendly (netty stays low
> level).
> 2. Make this server CDI friendly, basically a CDI bean and nice to have,
> configurable (port, ssl, ...) with MP-Config (or equivalent - if you take a
> Map<String, String> as input you won here),
> 3. Now you have to abstract the handler and make the default handler a
> facade for user handlers. User handlers are CDI beans. I would start by
> making them with something between servlet and jaxrs:
>
> @HttpHandler(method = {GET, POST}, url = "/foo", mathing = Matching.EXACT)
>
> method being the http method handled, url the urlpattern matched thanks the
> matching algo (i used an enum but it can be anything equivalent). EXACT
> means request path == url, we can envision wildcard matching (as in
> servlet), regex matching etc...
>
> The signature can start to be the exact expected one
> (CompletionStage<Response> onRequest(Request)) while validated in the cdi
> extension grabbing the handlers, then you can relax the CompletionStage
> requirement (Response onReq(Request)) and finally you can go closer to
> jaxrs adding @PathParam/@QueryParam/... like annotations but if Request API
> is nice enough it is not required in this layer - it can be a layer on top
> as jaxrs is on top of servlet. What's important here is to be reactive
> friendly by design - I'll let you play with the threading strategies to
> have an useful CompletionStage and how to link it - or not ;) - to netty
> executors.
>
> Once handlers well done, it is easy to add filters on top of it, same kind
> of API but it takes another optional parameter:
>
> CompletionStage<Response> onRequest(Request request,
> Supplier<CompletionStage<Response>> proceed);
>
> with proceed the call to filter N+1 and finally the handler (check out OWB
> interceptor impl, it is exactly the same.
>
> Last important point: ensure to handle @Priority (or add priority = int
> in @HttpHandler) cause when you will implement the matching chain you will
> need an order normally.
>
> Bonus: you can make the matching strategies pluggable if you want and just
> provide some defaults OOTB.
>
> Hope it makes sense.
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hello everyone,
>>
>> in the last month I have spent most of my time getting to know coding
>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
>> extensions which will be the technological foundation for the server.
>>
>> Next up will be defining and implementing the HTTP API, which will bring
>> CDI and Netty together. Feel free to contribute your thoughts on the
>> matter here on the mailing list or in the respective Jira issue:
>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>
>> @Romain: can you share some ideas, annotations, interfaces for how you
>> see the API roughly? Any kind of formal requirement-proposal would be
>> helpful to start with.
>>
>> Thanks and best regards,
>> Alexander
>>
>>

Re: GSOC 2020 progress update [Jira: OWB-1319]

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Alex,

The dump command can look like this (needs some enhancements since this one
was a simplified version but it can be a good start):
https://github.com/yupiik/jira-cli-native/blob/master/src/main/java/io/yupiik/jira/cli/command/impl/internal/dump/Dump.java#L58
The stable name setup is done with
https://github.com/yupiik/jira-cli-native/blob/master/src/main/java/io/yupiik/jira/cli/Cli.java#L37
The Spy setup is done in OWB services properties (openwebbeans.properties
or CDI SE properties:
https://github.com/yupiik/jira-cli-native/blob/master/src/main/java/io/yupiik/jira/cli/Cli.java#L36
)

You can't really create the services (proxy factory and spy) manually but
must let it be created by webbeanscontext which is the kind of IoC in OWB
core so you will pass them in the map parameter of webbeanscontext -
otherwise services will not be linked and you will not get the proxies
bytes in the Spy class.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le mer. 5 août 2020 à 14:48, Alexander Fischer
<fi...@mailbox.org.invalid> a écrit :

> Hey Romain,
>
> thanks for the infos the other day. I'm having difficulties using the
> Spy class that you mentioned though.
> Right now as an example I'm manually selecting some test classes to
> proxy and use the NormalScopeProxyFactory.createProxyClass() on them.
> But as we need a bytearray as return, I was looking at
> AbstractProxyFactory.generateProxy() instead.
> I don't quite figure out how to use the Spy with its defineAndLoad()
> method in this context yet, but it seems like the Spy would manage all
> this anyway.
> Could you elaborate a little bit further on this?
> Here's my sample code:
>
> https://github.com/a-rekkusu/graalvm-native-image-example/blob/master/src/main/java/de/arekkusu/proxyGeneration/BuildTimeProxyGenerator.java
>
> Thanks and best regards,
> Alex
>
> On 03.08.2020 16:00, Romain Manni-Bucau wrote:
> > Hi Alexander,
> >
> > We have a property for that:
> >
> https://github.com/apache/openwebbeans/blob/master/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java#L85
> > After you can run at build time a cdi container with
> > ClassLoaderProxyService.Spy on - can use CDI SE API, you iterate over all
> > beans and trigger the proxy generation for all the ones needing ones
> > (decorated, intercepted, ...) - just looking up an instance should be
> > sufficient since instantiation is lazy normally, just ensure it does not
> > trigger postconstruct or so.
> > Once done you lookup in WebBeansContext the Spy instance (needs to be
> > casted) then you have all proxies you can dump calling getProxies().
> > Finally the runtime just needs to setup ClassLoaderProxyService.LoadFirst
> > and ensure to have the dumped proxies in the classpath.
> >
> > Just these steps avoid generating the proxies at runtime but load them
> > assuming they exist (if not it will try to generate them).
> >
> > For GraalVM (native mode), you need to ensure the dumped proxies are in
> the
> > native-image classpath and part of the reflection metadata to ensure it
> > works.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le lun. 3 août 2020 à 15:32, Alexander Fischer
> > <fi...@mailbox.org.invalid> a écrit :
> >
> >> Hey Romain,
> >>
> >> since our last mails I have started to work on the native part of the
> >> story. I roughly got to know proxies, their use cases and bytecode
> >> enhancement with Byte-Buddy (as it also uses ASM, like OWB).
> >> For OWB, the next step towards a build time proxy generation is to apply
> >> static naming for the generated proxies, as we need fixed look-up names
> >> at native-image runtime.
> >> I'm currently looking into how naming is done in OWB and wonder if
> >> static proxy naming should be an option for the proxy generation or if
> >> it should always be static after we tackled this issue.
> >> Any thoughts on that?
> >>
> >> Thanks and best regards,
> >> Alex
> >>
> >>
>

Re: GSOC 2020 progress update [Jira: OWB-1319]

Posted by Alexander Fischer <fi...@mailbox.org.INVALID>.
Hey Romain,

thanks for the infos the other day. I'm having difficulties using the
Spy class that you mentioned though.
Right now as an example I'm manually selecting some test classes to
proxy and use the NormalScopeProxyFactory.createProxyClass() on them.
But as we need a bytearray as return, I was looking at
AbstractProxyFactory.generateProxy() instead.
I don't quite figure out how to use the Spy with its defineAndLoad()
method in this context yet, but it seems like the Spy would manage all
this anyway.
Could you elaborate a little bit further on this?
Here's my sample code:
https://github.com/a-rekkusu/graalvm-native-image-example/blob/master/src/main/java/de/arekkusu/proxyGeneration/BuildTimeProxyGenerator.java

Thanks and best regards,
Alex

On 03.08.2020 16:00, Romain Manni-Bucau wrote:
> Hi Alexander,
>
> We have a property for that:
> https://github.com/apache/openwebbeans/blob/master/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java#L85
> After you can run at build time a cdi container with
> ClassLoaderProxyService.Spy on - can use CDI SE API, you iterate over all
> beans and trigger the proxy generation for all the ones needing ones
> (decorated, intercepted, ...) - just looking up an instance should be
> sufficient since instantiation is lazy normally, just ensure it does not
> trigger postconstruct or so.
> Once done you lookup in WebBeansContext the Spy instance (needs to be
> casted) then you have all proxies you can dump calling getProxies().
> Finally the runtime just needs to setup ClassLoaderProxyService.LoadFirst
> and ensure to have the dumped proxies in the classpath.
>
> Just these steps avoid generating the proxies at runtime but load them
> assuming they exist (if not it will try to generate them).
>
> For GraalVM (native mode), you need to ensure the dumped proxies are in the
> native-image classpath and part of the reflection metadata to ensure it
> works.
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le lun. 3 août 2020 à 15:32, Alexander Fischer
> <fi...@mailbox.org.invalid> a écrit :
>
>> Hey Romain,
>>
>> since our last mails I have started to work on the native part of the
>> story. I roughly got to know proxies, their use cases and bytecode
>> enhancement with Byte-Buddy (as it also uses ASM, like OWB).
>> For OWB, the next step towards a build time proxy generation is to apply
>> static naming for the generated proxies, as we need fixed look-up names
>> at native-image runtime.
>> I'm currently looking into how naming is done in OWB and wonder if
>> static proxy naming should be an option for the proxy generation or if
>> it should always be static after we tackled this issue.
>> Any thoughts on that?
>>
>> Thanks and best regards,
>> Alex
>>
>>

Re: GSOC 2020 progress update [Jira: OWB-1319]

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Alexander,

We have a property for that:
https://github.com/apache/openwebbeans/blob/master/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java#L85
After you can run at build time a cdi container with
ClassLoaderProxyService.Spy on - can use CDI SE API, you iterate over all
beans and trigger the proxy generation for all the ones needing ones
(decorated, intercepted, ...) - just looking up an instance should be
sufficient since instantiation is lazy normally, just ensure it does not
trigger postconstruct or so.
Once done you lookup in WebBeansContext the Spy instance (needs to be
casted) then you have all proxies you can dump calling getProxies().
Finally the runtime just needs to setup ClassLoaderProxyService.LoadFirst
and ensure to have the dumped proxies in the classpath.

Just these steps avoid generating the proxies at runtime but load them
assuming they exist (if not it will try to generate them).

For GraalVM (native mode), you need to ensure the dumped proxies are in the
native-image classpath and part of the reflection metadata to ensure it
works.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le lun. 3 août 2020 à 15:32, Alexander Fischer
<fi...@mailbox.org.invalid> a écrit :

> Hey Romain,
>
> since our last mails I have started to work on the native part of the
> story. I roughly got to know proxies, their use cases and bytecode
> enhancement with Byte-Buddy (as it also uses ASM, like OWB).
> For OWB, the next step towards a build time proxy generation is to apply
> static naming for the generated proxies, as we need fixed look-up names
> at native-image runtime.
> I'm currently looking into how naming is done in OWB and wonder if
> static proxy naming should be an option for the proxy generation or if
> it should always be static after we tackled this issue.
> Any thoughts on that?
>
> Thanks and best regards,
> Alex
>
>

GSOC 2020 progress update [Jira: OWB-1319]

Posted by Alexander Fischer <fi...@mailbox.org.INVALID>.
Hey Romain,

since our last mails I have started to work on the native part of the
story. I roughly got to know proxies, their use cases and bytecode
enhancement with Byte-Buddy (as it also uses ASM, like OWB).
For OWB, the next step towards a build time proxy generation is to apply
static naming for the generated proxies, as we need fixed look-up names
at native-image runtime.
I'm currently looking into how naming is done in OWB and wonder if
static proxy naming should be an option for the proxy generation or if
it should always be static after we tackled this issue.
Any thoughts on that?

Thanks and best regards,
Alex


Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Alex,

Think it is ok for a first flavor (note that the scope of the server config
can be dependent since it is used once, the lookup creational context can
also be eagerly released).

In terms of impl a few notes - not required but while I'm in the code I
will mention it:

1. the startup can be async and a bean CompletionStage<HttpServerStatus>
can be added in cdi context to let the app wait for the server to be ready
if needed (or event block the startup)
2. the sync() call can be toggled by a flag in the config
3. if you handle a single server I guess a httpserver.properties can enable
to replace the config bean (or do the lookup of all httpserver instance to
start them all in afterDeploymentValidation)
4. (the only really important note) don't block CDI startup nor stop your
server just after starting it in afterDeploymentValidation - guess it is an
in progress part ;)


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le mer. 15 juil. 2020 à 14:52, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hey Romain,
>
> you can now take a look at the current state. A builder pattern is
> implemented, and in the showcase you can see how the server is
> configured and injected.
> https://github.com/a-rekkusu/owb-centric-microserver
>
> Please let me know what you think.
>
> Best regards,
> Alex
>
> On 08.07.2020 16:19, Romain Manni-Bucau wrote:
> > Le mer. 8 juil. 2020 à 14:42, Alexander Fischer <fi...@mailbox.org>
> a
> > écrit :
> >
> >> Hi Romain,
> >>
> >> thanks for the feedback. I made subtasks in Jira for the leftover server
> >> features and marked them for later.
> >> Regarding the configuration of our server, I took a look at how
> >> Meecrowave's Builder does it. Do you think it's a good idea to adopt
> >> this structure or should we build it another way?
> >>
> > Having a fluent API is good I think since it will often be created in a
> > producer, then you can use the flavor you like.
> > I tend to keep using fluent setters cause factories (xbean-finder,
> spring,
> > etc...) handle them more easily but not sure it is required there.
> >
> >
> >> And about the server as injectable bean: can you elaborate a bit about
> >> how you intend to use it and how it would be an advantage for you? What
> >> methods would you need available? Would it be like a container class
> >> that should contain all application scoped info (e.g. our HttpHandlers,
> >> the actual server)?
> >>
> > @Inject HttpServer server;
> >
> > String target = "http://localhost:" + server.getPort(); // ensure that
> if
> > the original port is 0 (random) then getPort returns the actual runtime
> port
> >
> > Host and if ssl is enabled are also useful info.
> >
> >
> >> Thanks and best regards,
> >> Alex
> >>
> >> On 06.07.2020 17:36, Romain Manni-Bucau wrote:
> >>> Hi Alex,
> >>>
> >>> A completionstage is just a promise so how it is wired is not that
> >>> important - it is not rare i don't use the fluent API for example but a
> >>> custom listener impl - but it is key to know in which thread context is
> >> it
> >>> executed.
> >>> Typically with your impl you inherit the caller threading - which can
> be
> >>> what you want or not. Concretely, while it is NOT netty NIOLoop threads
> >> it
> >>> is ok I think.
> >>> A small issue you can hit is the full http response is not chunking
> >>> compatible but it can be done in a second phase I guess.
> >>> In terms of global arch, you will also want to preresolve (see it as a
> >>> precompile phase) the execution (so no
> CDI.current().select(info.clazz).
> >>> get() at runtime but a resolve during the bootstrap or lazily but only
> >>> once). Same kind of side note for query params and form params, you
> >> likely
> >>> want to parse them lazily and call the decoder.destroy() in a finally
> >> block
> >>> ;).
> >>> That said, the showcase is already nice and this is pretty much details
> >>> since the structure is there and I guess it can be tackled after GSoC.
> >>>
> >>> Romain Manni-Bucau
> >>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>
> >>>
> >>> Le lun. 6 juil. 2020 à 17:03, Alexander Fischer <fischer.a@mailbox.org
> >
> >> a
> >>> écrit :
> >>>
> >>>> Hey Romain,
> >>>>
> >>>> the API, Netty and CDI are roughly working together now.
> >>>> How do you think we should handle the CompletionStage case in Netty?
> >>>> Should we handle it in Netty's ChannelFuture features or leave it out
> of
> >>>> there as CompletionStage does its work already?
> >>>> Right now I went with using ChannelFuture for CompletionStage. You can
> >>>> see the part here:
> >>>>
> >>>>
> >>>>
> >>
> https://github.com/a-rekkusu/owb-centric-microserver/blob/master/impl/src/main/java/org/apache/peeco/impl/HttpServerHandler.java#L69
> >>>> Please let me know what you think overall. Next up would be the
> >>>> configuration tasks (e.g. server as CDI bean).
> >>>> Regarding the schedule, GSOC is running until August 31st, so Thomas
> and
> >>>> I try to get started with the native part from next week onwards, as
> we
> >>>> slowly hit the middle of the project time.
> >>>>
> >>>> Best regards,
> >>>> Alex
> >>>>
> >>>> On 19.06.2020 16:49, Romain Manni-Bucau wrote:
> >>>>> Except Response.setOutput which should use a plain InputStream
> (instead
> >>>> of
> >>>>> byte array flavor) it looks ok
> >>>>>
> >>>>> About parameters, one option is to do a "return
> >>>>> Stream.concat(body.entrySet().stream(),
> >>>>> form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
> >>>>> Map.Entry::getValue, this::myMerger);" but impl is a detail for now
> ;).
> >>>>> Another - once again not blocking to impl - small note is you rarely
> >> use
> >>>>> body + param in the same request so it can be lazily instantiated
> >> (avoids
> >>>>> the parsing - netty has the needed classes to parse them) so a
> Supplier
> >>>> can
> >>>>> makes sense too, but this would be in the optim phase.
> >>>>>
> >>>>> In other words I think you can do a first impl with that API, then
> see
> >>>> how
> >>>>> to handle chunking and then only optimize the api internals, at least
> >> it
> >>>> is
> >>>>> how I would proceed.
> >>>>>
> >>>>> Romain Manni-Bucau
> >>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>> https://github.com/rmannibucau> |
> >>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>
> >>>>> Le ven. 19 juin 2020 à 15:53, Alexander Fischer <
> fischer.a@mailbox.org
> >>>> a
> >>>>> écrit :
> >>>>>
> >>>>>> Hi Romain,
> >>>>>>
> >>>>>> you are right with your points and I've tried to apply them. The
> >>>>>> Request.parameters() method might be solvable more elegantly. Only
> >>>>>> streams were a bit unclear to me, but I did it as I understood it
> for
> >>>>>> now (correct me if I got it wrong):
> >>>>>> the user writes/casts his intended output to a ByteArrayInputStream,
> >>>>>> which is handed over to netty that transforms it to its actual
> output
> >>>>>> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
> >>>>>> Let me know what you think of the current state, please. Once again
> >> the
> >>>>>> repo link, just for convenience.
> >>>>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>>>
> >>>>>> Thanks and best regards,
> >>>>>> Alex
> >>>>>>
> >>>>>> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
> >>>>>>> Should matching be an array? If so how would you impl it? (it is
> >>>>>> associated
> >>>>>>> with "url" or another parameter for its config, for instance EXACT
> +
> >>>> path
> >>>>>>> so i don't see how it would work to support EXACT and WILDCARD at
> the
> >>>>>> same
> >>>>>>> time for ex).
> >>>>>>> In Request ensure to return Map<String, List<String>> and not
> >>>>>>> HashMap<String, String> (it is not a hashmap cause headers are case
> >>>>>>> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better
> IMHO
> >>>> but
> >>>>>>> no need to expose the impl).
> >>>>>>> Parameters should likely be split in body parameters (form data)
> and
> >>>>>> query
> >>>>>>> parameters (so getParameter(String) would be a facade to 2 get in
> >> query
> >>>>>> and
> >>>>>>> form maps).
> >>>>>>> Kind of the same remark on the response (for HashMap) + payload is
> an
> >>>>>>> InputStream. This one requires some explanation:
> >>>>>>>
> >>>>>>> 1. Using a ByteArrayOutputStream is quite limiting since you drop
> all
> >>>>>>> decorations and oversized payload support
> >>>>>>> 2. An outputstream requires the server to know how to map this
> object
> >>>> to
> >>>>>>> something readable (input stream or the reactive equivalent)
> >>>>>>> 3. output stream will likely require the server to inject the
> >> instance
> >>>>>> once
> >>>>>>> 1 is fixed which is something we should try to avoid
> >>>>>>>
> >>>>>>> Now if you move to an Inputstream you can consumer it easily from
> the
> >>>>>>> server point of view, wrap it easily (in a filter for ex) and
> setting
> >>>> the
> >>>>>>> output is as easy:
> >>>>>>>
> >>>>>>> setOutput(new ByteArrayInputStream(...));
> >>>>>>> + the user friendly flavor(s): setOutput(String) (which does the
> >>>>>>> setoutput(inputStream) + setHeader(content-length))
> >>>>>>>
> >>>>>>> Romain Manni-Bucau
> >>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>>>> https://github.com/rmannibucau> |
> >>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>>> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <
> >> fischer.a@mailbox.org
> >>>>>> a
> >>>>>>> écrit :
> >>>>>>>
> >>>>>>>> Hey Romain,
> >>>>>>>>
> >>>>>>>> thanks for the feedback! I have implemented the API feedback now,
> >>>> please
> >>>>>>>> take another look:
> >>>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>>>>>
> >>>>>>>> Are there functionalities that you miss?
> >>>>>>>> Else, the Netty implementation ist next.
> >>>>>>>>
> >>>>>>>> Best regards,
> >>>>>>>> Alex
> >>>>>>>>
> >>>>>>>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> >>>>>>>>> Hi Alex,
> >>>>>>>>>
> >>>>>>>>> I don't think you need the HttpHandler annotation to be a
> qualifier
> >>>>>> (will
> >>>>>>>>> typically end up on a method not producing any bean at some
> point I
> >>>>>> think
> >>>>>>>>> as in the example at the end of this answer).
> >>>>>>>>> I guess Request/Response models are not yet done? Side note
> before
> >>>> you
> >>>>>>>> work
> >>>>>>>>> on them: maybe don't copy servlet API, content-type,
> content-length
> >>>> etc
> >>>>>>>> are
> >>>>>>>>> just headers, no need to make them specific, also prefer to set
> the
> >>>>>>>> payload
> >>>>>>>>> (as an inputstream or reactive stream) rather than encapsulating
> >>>>>>>> read/write
> >>>>>>>>> methods, it enables a better composition and decoration in
> general
> >>>> and
> >>>>>>>>> bypasses to go through a provider/factory to create
> >>>> requests/responses.
> >>>>>>>>> Last thing is you probably want to create a package for that work
> >> and
> >>>>>> not
> >>>>>>>>> use the default one ;).
> >>>>>>>>>
> >>>>>>>>> Typically it is a good start IMHO and once this works I'd do
> >> another
> >>>>>>>> small
> >>>>>>>>> iteration to end up on:
> >>>>>>>>>
> >>>>>>>>> public class HelloWorldHandlerFuture
> >>>>>>>>> {
> >>>>>>>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
> >>>>>> "/hello",
> >>>>>>>>> matching = Matching.EXACT)
> >>>>>>>>> public CompletionStage<Response> apply(Request request)
> >>>>>>>>> {
> >>>>>>>>> return CompletableFuture.supplyAsync(() ->
> >>>>>>>>> {
> >>>>>>>>> Response response = new Response();
> >>>>>>>>> response.setStatus(200);
> >>>>>>>>> response.write("Hello World from " + getClass().getName());
> >>>>>>>>> return response;
> >>>>>>>>> });
> >>>>>>>>> }
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>> Small side note (fully related to CompletionStage more than your
> >>>>>> current
> >>>>>>>>> work: if you want a synchronous impl of a CompletionStage you can
> >> use
> >>>>>>>>> CompletionFuture.completedFuture(response) - avoid the
> sypplyAsync
> >> -
> >>>>>> and
> >>>>>>>> if
> >>>>>>>>> you want to be async (sypplyAsync) ensure you pass an executor as
> >>>>>> second
> >>>>>>>>> parameter otherwise you end up being in default ForkJoinPool
> which
> >>>> has
> >>>>>> a
> >>>>>>>>> lot of side effects and limitations.
> >>>>>>>>>
> >>>>>>>>> Anyway, very good first iteration, it is pretty close to what I
> was
> >>>>>>>>> envisioning and it looks as smooth as I was thinking.
> >>>>>>>>>
> >>>>>>>>> Small tip for the impl phase (don't know if it is the next one or
> >>>> not):
> >>>>>>>> for
> >>>>>>>>> the handler registration, ensure to enable to do it
> >> programmatically:
> >>>>>>>>> register(Function<Request, CompletionStage<Response>>). It will
> >>>> enable
> >>>>>> to
> >>>>>>>>> use other models than the annotated one which is just a
> simplified
> >>>> API
> >>>>>> of
> >>>>>>>>> the actual one the server uses internally.
> >>>>>>>>>
> >>>>>>>>> Romain Manni-Bucau
> >>>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>>>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>>>>>> https://github.com/rmannibucau> |
> >>>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>>>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>>>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <
> >>>> fischer.a@mailbox.org
> >>>>>>>> a
> >>>>>>>>> écrit :
> >>>>>>>>>
> >>>>>>>>>> Hi Romain,
> >>>>>>>>>>
> >>>>>>>>>> I have made a first draft for the API and example showcase:
> >>>>>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>>>>>>>
> >>>>>>>>>> Please take a look and let me know what you think.
> >>>>>>>>>> CompletionStage is supported, but right now for all requests on
> a
> >>>>>>>>>> handler. If you would want a CompletableFuture only for POST for
> >>>>>>>>>> example, and not on GET, how do you think we should handle that?
> >>>>>>>>>> We could do it with a second HttpHandler on the same url but
> with
> >>>> the
> >>>>>>>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
> >>>>>>>> HelloWorldHandlerPost).
> >>>>>>>>>> Kind regards,
> >>>>>>>>>> Alex
> >>>>>>>>>>
> >>>>>>>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> >>>>>>>>>>> Hi Alex,
> >>>>>>>>>>>
> >>>>>>>>>>> Nothing is written in the stone but here is how I would
> approach
> >>>>>> that:
> >>>>>>>>>>> 1. Write a HTTP server able to call a handler to answer a
> >> request -
> >>>>>> you
> >>>>>>>>>> can
> >>>>>>>>>>> start by giving a hardcoded handler but in terms of design,
> >> ensure
> >>>>>> you
> >>>>>>>>>> get
> >>>>>>>>>>> something taking a Request abstracting as input and a Response
> >>>>>>>>>> abstraction
> >>>>>>>>>>> as output.
> >>>>>>>>>>> Netty has these abstraction but we don't want to depend on
> netty
> >> so
> >>>>>> you
> >>>>>>>>>>> should duplicate it making it even more user friendly (netty
> >> stays
> >>>>>> low
> >>>>>>>>>>> level).
> >>>>>>>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice
> >> to
> >>>>>>>> have,
> >>>>>>>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent -
> if
> >>>> you
> >>>>>>>>>> take a
> >>>>>>>>>>> Map<String, String> as input you won here),
> >>>>>>>>>>> 3. Now you have to abstract the handler and make the default
> >>>> handler
> >>>>>> a
> >>>>>>>>>>> facade for user handlers. User handlers are CDI beans. I would
> >>>> start
> >>>>>> by
> >>>>>>>>>>> making them with something between servlet and jaxrs:
> >>>>>>>>>>>
> >>>>>>>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> >>>>>>>>>> Matching.EXACT)
> >>>>>>>>>>> method being the http method handled, url the urlpattern
> matched
> >>>>>> thanks
> >>>>>>>>>> the
> >>>>>>>>>>> matching algo (i used an enum but it can be anything
> equivalent).
> >>>>>> EXACT
> >>>>>>>>>>> means request path == url, we can envision wildcard matching
> (as
> >> in
> >>>>>>>>>>> servlet), regex matching etc...
> >>>>>>>>>>>
> >>>>>>>>>>> The signature can start to be the exact expected one
> >>>>>>>>>>> (CompletionStage<Response> onRequest(Request)) while validated
> in
> >>>> the
> >>>>>>>> cdi
> >>>>>>>>>>> extension grabbing the handlers, then you can relax the
> >>>>>> CompletionStage
> >>>>>>>>>>> requirement (Response onReq(Request)) and finally you can go
> >> closer
> >>>>>> to
> >>>>>>>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
> >>>>>> Request
> >>>>>>>>>> API
> >>>>>>>>>>> is nice enough it is not required in this layer - it can be a
> >> layer
> >>>>>> on
> >>>>>>>>>> top
> >>>>>>>>>>> as jaxrs is on top of servlet. What's important here is to be
> >>>>>> reactive
> >>>>>>>>>>> friendly by design - I'll let you play with the threading
> >>>> strategies
> >>>>>> to
> >>>>>>>>>>> have an useful CompletionStage and how to link it - or not ;) -
> >> to
> >>>>>>>> netty
> >>>>>>>>>>> executors.
> >>>>>>>>>>>
> >>>>>>>>>>> Once handlers well done, it is easy to add filters on top of
> it,
> >>>> same
> >>>>>>>>>> kind
> >>>>>>>>>>> of API but it takes another optional parameter:
> >>>>>>>>>>>
> >>>>>>>>>>> CompletionStage<Response> onRequest(Request request,
> >>>>>>>>>>> Supplier<CompletionStage<Response>> proceed);
> >>>>>>>>>>>
> >>>>>>>>>>> with proceed the call to filter N+1 and finally the handler
> >> (check
> >>>>>> out
> >>>>>>>>>> OWB
> >>>>>>>>>>> interceptor impl, it is exactly the same.
> >>>>>>>>>>>
> >>>>>>>>>>> Last important point: ensure to handle @Priority (or add
> >> priority =
> >>>>>> int
> >>>>>>>>>>> in @HttpHandler) cause when you will implement the matching
> chain
> >>>> you
> >>>>>>>>>> will
> >>>>>>>>>>> need an order normally.
> >>>>>>>>>>>
> >>>>>>>>>>> Bonus: you can make the matching strategies pluggable if you
> want
> >>>> and
> >>>>>>>>>> just
> >>>>>>>>>>> provide some defaults OOTB.
> >>>>>>>>>>>
> >>>>>>>>>>> Hope it makes sense.
> >>>>>>>>>>>
> >>>>>>>>>>> Romain Manni-Bucau
> >>>>>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>>>>>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>>>>>>>> https://github.com/rmannibucau> |
> >>>>>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>>>>>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>>>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
> >>>>>> fischer.a@mailbox.org>
> >>>>>>>> a
> >>>>>>>>>>> écrit :
> >>>>>>>>>>>
> >>>>>>>>>>>> Hello everyone,
> >>>>>>>>>>>>
> >>>>>>>>>>>> in the last month I have spent most of my time getting to know
> >>>>>> coding
> >>>>>>>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to
> >> know
> >>>>>> CDI
> >>>>>>>>>>>> extensions which will be the technological foundation for the
> >>>>>> server.
> >>>>>>>>>>>> Next up will be defining and implementing the HTTP API, which
> >> will
> >>>>>>>> bring
> >>>>>>>>>>>> CDI and Netty together. Feel free to contribute your thoughts
> on
> >>>> the
> >>>>>>>>>>>> matter here on the mailing list or in the respective Jira
> issue:
> >>>>>>>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>>>>>>>>>>>
> >>>>>>>>>>>> @Romain: can you share some ideas, annotations, interfaces for
> >> how
> >>>>>> you
> >>>>>>>>>>>> see the API roughly? Any kind of formal requirement-proposal
> >> would
> >>>>>> be
> >>>>>>>>>>>> helpful to start with.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Thanks and best regards,
> >>>>>>>>>>>> Alexander
> >>>>>>>>>>>>
> >>>>>>>>>>>>
>

Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hey Romain,

you can now take a look at the current state. A builder pattern is
implemented, and in the showcase you can see how the server is
configured and injected.
https://github.com/a-rekkusu/owb-centric-microserver

Please let me know what you think.

Best regards,
Alex

On 08.07.2020 16:19, Romain Manni-Bucau wrote:
> Le mer. 8 juil. 2020 à 14:42, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hi Romain,
>>
>> thanks for the feedback. I made subtasks in Jira for the leftover server
>> features and marked them for later.
>> Regarding the configuration of our server, I took a look at how
>> Meecrowave's Builder does it. Do you think it's a good idea to adopt
>> this structure or should we build it another way?
>>
> Having a fluent API is good I think since it will often be created in a
> producer, then you can use the flavor you like.
> I tend to keep using fluent setters cause factories (xbean-finder, spring,
> etc...) handle them more easily but not sure it is required there.
>
>
>> And about the server as injectable bean: can you elaborate a bit about
>> how you intend to use it and how it would be an advantage for you? What
>> methods would you need available? Would it be like a container class
>> that should contain all application scoped info (e.g. our HttpHandlers,
>> the actual server)?
>>
> @Inject HttpServer server;
>
> String target = "http://localhost:" + server.getPort(); // ensure that if
> the original port is 0 (random) then getPort returns the actual runtime port
>
> Host and if ssl is enabled are also useful info.
>
>
>> Thanks and best regards,
>> Alex
>>
>> On 06.07.2020 17:36, Romain Manni-Bucau wrote:
>>> Hi Alex,
>>>
>>> A completionstage is just a promise so how it is wired is not that
>>> important - it is not rare i don't use the fluent API for example but a
>>> custom listener impl - but it is key to know in which thread context is
>> it
>>> executed.
>>> Typically with your impl you inherit the caller threading - which can be
>>> what you want or not. Concretely, while it is NOT netty NIOLoop threads
>> it
>>> is ok I think.
>>> A small issue you can hit is the full http response is not chunking
>>> compatible but it can be done in a second phase I guess.
>>> In terms of global arch, you will also want to preresolve (see it as a
>>> precompile phase) the execution (so no CDI.current().select(info.clazz).
>>> get() at runtime but a resolve during the bootstrap or lazily but only
>>> once). Same kind of side note for query params and form params, you
>> likely
>>> want to parse them lazily and call the decoder.destroy() in a finally
>> block
>>> ;).
>>> That said, the showcase is already nice and this is pretty much details
>>> since the structure is there and I guess it can be tackled after GSoC.
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>> <http://rmannibucau.wordpress.com> | Github <
>> https://github.com/rmannibucau> |
>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>
>>>
>>> Le lun. 6 juil. 2020 à 17:03, Alexander Fischer <fi...@mailbox.org>
>> a
>>> écrit :
>>>
>>>> Hey Romain,
>>>>
>>>> the API, Netty and CDI are roughly working together now.
>>>> How do you think we should handle the CompletionStage case in Netty?
>>>> Should we handle it in Netty's ChannelFuture features or leave it out of
>>>> there as CompletionStage does its work already?
>>>> Right now I went with using ChannelFuture for CompletionStage. You can
>>>> see the part here:
>>>>
>>>>
>>>>
>> https://github.com/a-rekkusu/owb-centric-microserver/blob/master/impl/src/main/java/org/apache/peeco/impl/HttpServerHandler.java#L69
>>>> Please let me know what you think overall. Next up would be the
>>>> configuration tasks (e.g. server as CDI bean).
>>>> Regarding the schedule, GSOC is running until August 31st, so Thomas and
>>>> I try to get started with the native part from next week onwards, as we
>>>> slowly hit the middle of the project time.
>>>>
>>>> Best regards,
>>>> Alex
>>>>
>>>> On 19.06.2020 16:49, Romain Manni-Bucau wrote:
>>>>> Except Response.setOutput which should use a plain InputStream (instead
>>>> of
>>>>> byte array flavor) it looks ok
>>>>>
>>>>> About parameters, one option is to do a "return
>>>>> Stream.concat(body.entrySet().stream(),
>>>>> form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
>>>>> Map.Entry::getValue, this::myMerger);" but impl is a detail for now ;).
>>>>> Another - once again not blocking to impl - small note is you rarely
>> use
>>>>> body + param in the same request so it can be lazily instantiated
>> (avoids
>>>>> the parsing - netty has the needed classes to parse them) so a Supplier
>>>> can
>>>>> makes sense too, but this would be in the optim phase.
>>>>>
>>>>> In other words I think you can do a first impl with that API, then see
>>>> how
>>>>> to handle chunking and then only optimize the api internals, at least
>> it
>>>> is
>>>>> how I would proceed.
>>>>>
>>>>> Romain Manni-Bucau
>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>> https://github.com/rmannibucau> |
>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>
>>>>> Le ven. 19 juin 2020 à 15:53, Alexander Fischer <fischer.a@mailbox.org
>>>> a
>>>>> écrit :
>>>>>
>>>>>> Hi Romain,
>>>>>>
>>>>>> you are right with your points and I've tried to apply them. The
>>>>>> Request.parameters() method might be solvable more elegantly. Only
>>>>>> streams were a bit unclear to me, but I did it as I understood it for
>>>>>> now (correct me if I got it wrong):
>>>>>> the user writes/casts his intended output to a ByteArrayInputStream,
>>>>>> which is handed over to netty that transforms it to its actual output
>>>>>> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
>>>>>> Let me know what you think of the current state, please. Once again
>> the
>>>>>> repo link, just for convenience.
>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>>>
>>>>>> Thanks and best regards,
>>>>>> Alex
>>>>>>
>>>>>> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
>>>>>>> Should matching be an array? If so how would you impl it? (it is
>>>>>> associated
>>>>>>> with "url" or another parameter for its config, for instance EXACT +
>>>> path
>>>>>>> so i don't see how it would work to support EXACT and WILDCARD at the
>>>>>> same
>>>>>>> time for ex).
>>>>>>> In Request ensure to return Map<String, List<String>> and not
>>>>>>> HashMap<String, String> (it is not a hashmap cause headers are case
>>>>>>> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO
>>>> but
>>>>>>> no need to expose the impl).
>>>>>>> Parameters should likely be split in body parameters (form data) and
>>>>>> query
>>>>>>> parameters (so getParameter(String) would be a facade to 2 get in
>> query
>>>>>> and
>>>>>>> form maps).
>>>>>>> Kind of the same remark on the response (for HashMap) + payload is an
>>>>>>> InputStream. This one requires some explanation:
>>>>>>>
>>>>>>> 1. Using a ByteArrayOutputStream is quite limiting since you drop all
>>>>>>> decorations and oversized payload support
>>>>>>> 2. An outputstream requires the server to know how to map this object
>>>> to
>>>>>>> something readable (input stream or the reactive equivalent)
>>>>>>> 3. output stream will likely require the server to inject the
>> instance
>>>>>> once
>>>>>>> 1 is fixed which is something we should try to avoid
>>>>>>>
>>>>>>> Now if you move to an Inputstream you can consumer it easily from the
>>>>>>> server point of view, wrap it easily (in a filter for ex) and setting
>>>> the
>>>>>>> output is as easy:
>>>>>>>
>>>>>>> setOutput(new ByteArrayInputStream(...));
>>>>>>> + the user friendly flavor(s): setOutput(String) (which does the
>>>>>>> setoutput(inputStream) + setHeader(content-length))
>>>>>>>
>>>>>>> Romain Manni-Bucau
>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>>>> https://github.com/rmannibucau> |
>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>>> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <
>> fischer.a@mailbox.org
>>>>>> a
>>>>>>> écrit :
>>>>>>>
>>>>>>>> Hey Romain,
>>>>>>>>
>>>>>>>> thanks for the feedback! I have implemented the API feedback now,
>>>> please
>>>>>>>> take another look:
>>>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>>>>>
>>>>>>>> Are there functionalities that you miss?
>>>>>>>> Else, the Netty implementation ist next.
>>>>>>>>
>>>>>>>> Best regards,
>>>>>>>> Alex
>>>>>>>>
>>>>>>>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
>>>>>>>>> Hi Alex,
>>>>>>>>>
>>>>>>>>> I don't think you need the HttpHandler annotation to be a qualifier
>>>>>> (will
>>>>>>>>> typically end up on a method not producing any bean at some point I
>>>>>> think
>>>>>>>>> as in the example at the end of this answer).
>>>>>>>>> I guess Request/Response models are not yet done? Side note before
>>>> you
>>>>>>>> work
>>>>>>>>> on them: maybe don't copy servlet API, content-type, content-length
>>>> etc
>>>>>>>> are
>>>>>>>>> just headers, no need to make them specific, also prefer to set the
>>>>>>>> payload
>>>>>>>>> (as an inputstream or reactive stream) rather than encapsulating
>>>>>>>> read/write
>>>>>>>>> methods, it enables a better composition and decoration in general
>>>> and
>>>>>>>>> bypasses to go through a provider/factory to create
>>>> requests/responses.
>>>>>>>>> Last thing is you probably want to create a package for that work
>> and
>>>>>> not
>>>>>>>>> use the default one ;).
>>>>>>>>>
>>>>>>>>> Typically it is a good start IMHO and once this works I'd do
>> another
>>>>>>>> small
>>>>>>>>> iteration to end up on:
>>>>>>>>>
>>>>>>>>> public class HelloWorldHandlerFuture
>>>>>>>>> {
>>>>>>>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
>>>>>> "/hello",
>>>>>>>>> matching = Matching.EXACT)
>>>>>>>>> public CompletionStage<Response> apply(Request request)
>>>>>>>>> {
>>>>>>>>> return CompletableFuture.supplyAsync(() ->
>>>>>>>>> {
>>>>>>>>> Response response = new Response();
>>>>>>>>> response.setStatus(200);
>>>>>>>>> response.write("Hello World from " + getClass().getName());
>>>>>>>>> return response;
>>>>>>>>> });
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> Small side note (fully related to CompletionStage more than your
>>>>>> current
>>>>>>>>> work: if you want a synchronous impl of a CompletionStage you can
>> use
>>>>>>>>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync
>> -
>>>>>> and
>>>>>>>> if
>>>>>>>>> you want to be async (sypplyAsync) ensure you pass an executor as
>>>>>> second
>>>>>>>>> parameter otherwise you end up being in default ForkJoinPool which
>>>> has
>>>>>> a
>>>>>>>>> lot of side effects and limitations.
>>>>>>>>>
>>>>>>>>> Anyway, very good first iteration, it is pretty close to what I was
>>>>>>>>> envisioning and it looks as smooth as I was thinking.
>>>>>>>>>
>>>>>>>>> Small tip for the impl phase (don't know if it is the next one or
>>>> not):
>>>>>>>> for
>>>>>>>>> the handler registration, ensure to enable to do it
>> programmatically:
>>>>>>>>> register(Function<Request, CompletionStage<Response>>). It will
>>>> enable
>>>>>> to
>>>>>>>>> use other models than the annotated one which is just a simplified
>>>> API
>>>>>> of
>>>>>>>>> the actual one the server uses internally.
>>>>>>>>>
>>>>>>>>> Romain Manni-Bucau
>>>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>>>>>> https://github.com/rmannibucau> |
>>>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>>>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <
>>>> fischer.a@mailbox.org
>>>>>>>> a
>>>>>>>>> écrit :
>>>>>>>>>
>>>>>>>>>> Hi Romain,
>>>>>>>>>>
>>>>>>>>>> I have made a first draft for the API and example showcase:
>>>>>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>>>>>>>
>>>>>>>>>> Please take a look and let me know what you think.
>>>>>>>>>> CompletionStage is supported, but right now for all requests on a
>>>>>>>>>> handler. If you would want a CompletableFuture only for POST for
>>>>>>>>>> example, and not on GET, how do you think we should handle that?
>>>>>>>>>> We could do it with a second HttpHandler on the same url but with
>>>> the
>>>>>>>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
>>>>>>>> HelloWorldHandlerPost).
>>>>>>>>>> Kind regards,
>>>>>>>>>> Alex
>>>>>>>>>>
>>>>>>>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
>>>>>>>>>>> Hi Alex,
>>>>>>>>>>>
>>>>>>>>>>> Nothing is written in the stone but here is how I would approach
>>>>>> that:
>>>>>>>>>>> 1. Write a HTTP server able to call a handler to answer a
>> request -
>>>>>> you
>>>>>>>>>> can
>>>>>>>>>>> start by giving a hardcoded handler but in terms of design,
>> ensure
>>>>>> you
>>>>>>>>>> get
>>>>>>>>>>> something taking a Request abstracting as input and a Response
>>>>>>>>>> abstraction
>>>>>>>>>>> as output.
>>>>>>>>>>> Netty has these abstraction but we don't want to depend on netty
>> so
>>>>>> you
>>>>>>>>>>> should duplicate it making it even more user friendly (netty
>> stays
>>>>>> low
>>>>>>>>>>> level).
>>>>>>>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice
>> to
>>>>>>>> have,
>>>>>>>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if
>>>> you
>>>>>>>>>> take a
>>>>>>>>>>> Map<String, String> as input you won here),
>>>>>>>>>>> 3. Now you have to abstract the handler and make the default
>>>> handler
>>>>>> a
>>>>>>>>>>> facade for user handlers. User handlers are CDI beans. I would
>>>> start
>>>>>> by
>>>>>>>>>>> making them with something between servlet and jaxrs:
>>>>>>>>>>>
>>>>>>>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
>>>>>>>>>> Matching.EXACT)
>>>>>>>>>>> method being the http method handled, url the urlpattern matched
>>>>>> thanks
>>>>>>>>>> the
>>>>>>>>>>> matching algo (i used an enum but it can be anything equivalent).
>>>>>> EXACT
>>>>>>>>>>> means request path == url, we can envision wildcard matching (as
>> in
>>>>>>>>>>> servlet), regex matching etc...
>>>>>>>>>>>
>>>>>>>>>>> The signature can start to be the exact expected one
>>>>>>>>>>> (CompletionStage<Response> onRequest(Request)) while validated in
>>>> the
>>>>>>>> cdi
>>>>>>>>>>> extension grabbing the handlers, then you can relax the
>>>>>> CompletionStage
>>>>>>>>>>> requirement (Response onReq(Request)) and finally you can go
>> closer
>>>>>> to
>>>>>>>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
>>>>>> Request
>>>>>>>>>> API
>>>>>>>>>>> is nice enough it is not required in this layer - it can be a
>> layer
>>>>>> on
>>>>>>>>>> top
>>>>>>>>>>> as jaxrs is on top of servlet. What's important here is to be
>>>>>> reactive
>>>>>>>>>>> friendly by design - I'll let you play with the threading
>>>> strategies
>>>>>> to
>>>>>>>>>>> have an useful CompletionStage and how to link it - or not ;) -
>> to
>>>>>>>> netty
>>>>>>>>>>> executors.
>>>>>>>>>>>
>>>>>>>>>>> Once handlers well done, it is easy to add filters on top of it,
>>>> same
>>>>>>>>>> kind
>>>>>>>>>>> of API but it takes another optional parameter:
>>>>>>>>>>>
>>>>>>>>>>> CompletionStage<Response> onRequest(Request request,
>>>>>>>>>>> Supplier<CompletionStage<Response>> proceed);
>>>>>>>>>>>
>>>>>>>>>>> with proceed the call to filter N+1 and finally the handler
>> (check
>>>>>> out
>>>>>>>>>> OWB
>>>>>>>>>>> interceptor impl, it is exactly the same.
>>>>>>>>>>>
>>>>>>>>>>> Last important point: ensure to handle @Priority (or add
>> priority =
>>>>>> int
>>>>>>>>>>> in @HttpHandler) cause when you will implement the matching chain
>>>> you
>>>>>>>>>> will
>>>>>>>>>>> need an order normally.
>>>>>>>>>>>
>>>>>>>>>>> Bonus: you can make the matching strategies pluggable if you want
>>>> and
>>>>>>>>>> just
>>>>>>>>>>> provide some defaults OOTB.
>>>>>>>>>>>
>>>>>>>>>>> Hope it makes sense.
>>>>>>>>>>>
>>>>>>>>>>> Romain Manni-Bucau
>>>>>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>>>>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>>>>>>>> https://github.com/rmannibucau> |
>>>>>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>>>>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>>>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
>>>>>> fischer.a@mailbox.org>
>>>>>>>> a
>>>>>>>>>>> écrit :
>>>>>>>>>>>
>>>>>>>>>>>> Hello everyone,
>>>>>>>>>>>>
>>>>>>>>>>>> in the last month I have spent most of my time getting to know
>>>>>> coding
>>>>>>>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to
>> know
>>>>>> CDI
>>>>>>>>>>>> extensions which will be the technological foundation for the
>>>>>> server.
>>>>>>>>>>>> Next up will be defining and implementing the HTTP API, which
>> will
>>>>>>>> bring
>>>>>>>>>>>> CDI and Netty together. Feel free to contribute your thoughts on
>>>> the
>>>>>>>>>>>> matter here on the mailing list or in the respective Jira issue:
>>>>>>>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>>>>>>>>>>>
>>>>>>>>>>>> @Romain: can you share some ideas, annotations, interfaces for
>> how
>>>>>> you
>>>>>>>>>>>> see the API roughly? Any kind of formal requirement-proposal
>> would
>>>>>> be
>>>>>>>>>>>> helpful to start with.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks and best regards,
>>>>>>>>>>>> Alexander
>>>>>>>>>>>>
>>>>>>>>>>>>

Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Le mer. 8 juil. 2020 à 14:42, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hi Romain,
>
> thanks for the feedback. I made subtasks in Jira for the leftover server
> features and marked them for later.
> Regarding the configuration of our server, I took a look at how
> Meecrowave's Builder does it. Do you think it's a good idea to adopt
> this structure or should we build it another way?
>

Having a fluent API is good I think since it will often be created in a
producer, then you can use the flavor you like.
I tend to keep using fluent setters cause factories (xbean-finder, spring,
etc...) handle them more easily but not sure it is required there.


> And about the server as injectable bean: can you elaborate a bit about
> how you intend to use it and how it would be an advantage for you? What
> methods would you need available? Would it be like a container class
> that should contain all application scoped info (e.g. our HttpHandlers,
> the actual server)?
>

@Inject HttpServer server;

String target = "http://localhost:" + server.getPort(); // ensure that if
the original port is 0 (random) then getPort returns the actual runtime port

Host and if ssl is enabled are also useful info.


>
> Thanks and best regards,
> Alex
>
> On 06.07.2020 17:36, Romain Manni-Bucau wrote:
> > Hi Alex,
> >
> > A completionstage is just a promise so how it is wired is not that
> > important - it is not rare i don't use the fluent API for example but a
> > custom listener impl - but it is key to know in which thread context is
> it
> > executed.
> > Typically with your impl you inherit the caller threading - which can be
> > what you want or not. Concretely, while it is NOT netty NIOLoop threads
> it
> > is ok I think.
> > A small issue you can hit is the full http response is not chunking
> > compatible but it can be done in a second phase I guess.
> > In terms of global arch, you will also want to preresolve (see it as a
> > precompile phase) the execution (so no CDI.current().select(info.clazz).
> > get() at runtime but a resolve during the bootstrap or lazily but only
> > once). Same kind of side note for query params and form params, you
> likely
> > want to parse them lazily and call the decoder.destroy() in a finally
> block
> > ;).
> > That said, the showcase is already nice and this is pretty much details
> > since the structure is there and I guess it can be tackled after GSoC.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le lun. 6 juil. 2020 à 17:03, Alexander Fischer <fi...@mailbox.org>
> a
> > écrit :
> >
> >> Hey Romain,
> >>
> >> the API, Netty and CDI are roughly working together now.
> >> How do you think we should handle the CompletionStage case in Netty?
> >> Should we handle it in Netty's ChannelFuture features or leave it out of
> >> there as CompletionStage does its work already?
> >> Right now I went with using ChannelFuture for CompletionStage. You can
> >> see the part here:
> >>
> >>
> >>
> https://github.com/a-rekkusu/owb-centric-microserver/blob/master/impl/src/main/java/org/apache/peeco/impl/HttpServerHandler.java#L69
> >>
> >> Please let me know what you think overall. Next up would be the
> >> configuration tasks (e.g. server as CDI bean).
> >> Regarding the schedule, GSOC is running until August 31st, so Thomas and
> >> I try to get started with the native part from next week onwards, as we
> >> slowly hit the middle of the project time.
> >>
> >> Best regards,
> >> Alex
> >>
> >> On 19.06.2020 16:49, Romain Manni-Bucau wrote:
> >>> Except Response.setOutput which should use a plain InputStream (instead
> >> of
> >>> byte array flavor) it looks ok
> >>>
> >>> About parameters, one option is to do a "return
> >>> Stream.concat(body.entrySet().stream(),
> >>> form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
> >>> Map.Entry::getValue, this::myMerger);" but impl is a detail for now ;).
> >>> Another - once again not blocking to impl - small note is you rarely
> use
> >>> body + param in the same request so it can be lazily instantiated
> (avoids
> >>> the parsing - netty has the needed classes to parse them) so a Supplier
> >> can
> >>> makes sense too, but this would be in the optim phase.
> >>>
> >>> In other words I think you can do a first impl with that API, then see
> >> how
> >>> to handle chunking and then only optimize the api internals, at least
> it
> >> is
> >>> how I would proceed.
> >>>
> >>> Romain Manni-Bucau
> >>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>
> >>>
> >>> Le ven. 19 juin 2020 à 15:53, Alexander Fischer <fischer.a@mailbox.org
> >
> >> a
> >>> écrit :
> >>>
> >>>> Hi Romain,
> >>>>
> >>>> you are right with your points and I've tried to apply them. The
> >>>> Request.parameters() method might be solvable more elegantly. Only
> >>>> streams were a bit unclear to me, but I did it as I understood it for
> >>>> now (correct me if I got it wrong):
> >>>> the user writes/casts his intended output to a ByteArrayInputStream,
> >>>> which is handed over to netty that transforms it to its actual output
> >>>> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
> >>>> Let me know what you think of the current state, please. Once again
> the
> >>>> repo link, just for convenience.
> >>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>
> >>>> Thanks and best regards,
> >>>> Alex
> >>>>
> >>>> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
> >>>>> Should matching be an array? If so how would you impl it? (it is
> >>>> associated
> >>>>> with "url" or another parameter for its config, for instance EXACT +
> >> path
> >>>>> so i don't see how it would work to support EXACT and WILDCARD at the
> >>>> same
> >>>>> time for ex).
> >>>>> In Request ensure to return Map<String, List<String>> and not
> >>>>> HashMap<String, String> (it is not a hashmap cause headers are case
> >>>>> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO
> >> but
> >>>>> no need to expose the impl).
> >>>>> Parameters should likely be split in body parameters (form data) and
> >>>> query
> >>>>> parameters (so getParameter(String) would be a facade to 2 get in
> query
> >>>> and
> >>>>> form maps).
> >>>>> Kind of the same remark on the response (for HashMap) + payload is an
> >>>>> InputStream. This one requires some explanation:
> >>>>>
> >>>>> 1. Using a ByteArrayOutputStream is quite limiting since you drop all
> >>>>> decorations and oversized payload support
> >>>>> 2. An outputstream requires the server to know how to map this object
> >> to
> >>>>> something readable (input stream or the reactive equivalent)
> >>>>> 3. output stream will likely require the server to inject the
> instance
> >>>> once
> >>>>> 1 is fixed which is something we should try to avoid
> >>>>>
> >>>>> Now if you move to an Inputstream you can consumer it easily from the
> >>>>> server point of view, wrap it easily (in a filter for ex) and setting
> >> the
> >>>>> output is as easy:
> >>>>>
> >>>>> setOutput(new ByteArrayInputStream(...));
> >>>>> + the user friendly flavor(s): setOutput(String) (which does the
> >>>>> setoutput(inputStream) + setHeader(content-length))
> >>>>>
> >>>>> Romain Manni-Bucau
> >>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>> https://github.com/rmannibucau> |
> >>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>
> >>>>> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <
> fischer.a@mailbox.org
> >>>> a
> >>>>> écrit :
> >>>>>
> >>>>>> Hey Romain,
> >>>>>>
> >>>>>> thanks for the feedback! I have implemented the API feedback now,
> >> please
> >>>>>> take another look:
> >>>>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>>>
> >>>>>> Are there functionalities that you miss?
> >>>>>> Else, the Netty implementation ist next.
> >>>>>>
> >>>>>> Best regards,
> >>>>>> Alex
> >>>>>>
> >>>>>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> >>>>>>> Hi Alex,
> >>>>>>>
> >>>>>>> I don't think you need the HttpHandler annotation to be a qualifier
> >>>> (will
> >>>>>>> typically end up on a method not producing any bean at some point I
> >>>> think
> >>>>>>> as in the example at the end of this answer).
> >>>>>>> I guess Request/Response models are not yet done? Side note before
> >> you
> >>>>>> work
> >>>>>>> on them: maybe don't copy servlet API, content-type, content-length
> >> etc
> >>>>>> are
> >>>>>>> just headers, no need to make them specific, also prefer to set the
> >>>>>> payload
> >>>>>>> (as an inputstream or reactive stream) rather than encapsulating
> >>>>>> read/write
> >>>>>>> methods, it enables a better composition and decoration in general
> >> and
> >>>>>>> bypasses to go through a provider/factory to create
> >> requests/responses.
> >>>>>>> Last thing is you probably want to create a package for that work
> and
> >>>> not
> >>>>>>> use the default one ;).
> >>>>>>>
> >>>>>>> Typically it is a good start IMHO and once this works I'd do
> another
> >>>>>> small
> >>>>>>> iteration to end up on:
> >>>>>>>
> >>>>>>> public class HelloWorldHandlerFuture
> >>>>>>> {
> >>>>>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
> >>>> "/hello",
> >>>>>>> matching = Matching.EXACT)
> >>>>>>> public CompletionStage<Response> apply(Request request)
> >>>>>>> {
> >>>>>>> return CompletableFuture.supplyAsync(() ->
> >>>>>>> {
> >>>>>>> Response response = new Response();
> >>>>>>> response.setStatus(200);
> >>>>>>> response.write("Hello World from " + getClass().getName());
> >>>>>>> return response;
> >>>>>>> });
> >>>>>>> }
> >>>>>>> }
> >>>>>>>
> >>>>>>> Small side note (fully related to CompletionStage more than your
> >>>> current
> >>>>>>> work: if you want a synchronous impl of a CompletionStage you can
> use
> >>>>>>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync
> -
> >>>> and
> >>>>>> if
> >>>>>>> you want to be async (sypplyAsync) ensure you pass an executor as
> >>>> second
> >>>>>>> parameter otherwise you end up being in default ForkJoinPool which
> >> has
> >>>> a
> >>>>>>> lot of side effects and limitations.
> >>>>>>>
> >>>>>>> Anyway, very good first iteration, it is pretty close to what I was
> >>>>>>> envisioning and it looks as smooth as I was thinking.
> >>>>>>>
> >>>>>>> Small tip for the impl phase (don't know if it is the next one or
> >> not):
> >>>>>> for
> >>>>>>> the handler registration, ensure to enable to do it
> programmatically:
> >>>>>>> register(Function<Request, CompletionStage<Response>>). It will
> >> enable
> >>>> to
> >>>>>>> use other models than the annotated one which is just a simplified
> >> API
> >>>> of
> >>>>>>> the actual one the server uses internally.
> >>>>>>>
> >>>>>>> Romain Manni-Bucau
> >>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>>>> https://github.com/rmannibucau> |
> >>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <
> >> fischer.a@mailbox.org
> >>>>>> a
> >>>>>>> écrit :
> >>>>>>>
> >>>>>>>> Hi Romain,
> >>>>>>>>
> >>>>>>>> I have made a first draft for the API and example showcase:
> >>>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>>>>>
> >>>>>>>> Please take a look and let me know what you think.
> >>>>>>>> CompletionStage is supported, but right now for all requests on a
> >>>>>>>> handler. If you would want a CompletableFuture only for POST for
> >>>>>>>> example, and not on GET, how do you think we should handle that?
> >>>>>>>> We could do it with a second HttpHandler on the same url but with
> >> the
> >>>>>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
> >>>>>> HelloWorldHandlerPost).
> >>>>>>>> Kind regards,
> >>>>>>>> Alex
> >>>>>>>>
> >>>>>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> >>>>>>>>> Hi Alex,
> >>>>>>>>>
> >>>>>>>>> Nothing is written in the stone but here is how I would approach
> >>>> that:
> >>>>>>>>> 1. Write a HTTP server able to call a handler to answer a
> request -
> >>>> you
> >>>>>>>> can
> >>>>>>>>> start by giving a hardcoded handler but in terms of design,
> ensure
> >>>> you
> >>>>>>>> get
> >>>>>>>>> something taking a Request abstracting as input and a Response
> >>>>>>>> abstraction
> >>>>>>>>> as output.
> >>>>>>>>> Netty has these abstraction but we don't want to depend on netty
> so
> >>>> you
> >>>>>>>>> should duplicate it making it even more user friendly (netty
> stays
> >>>> low
> >>>>>>>>> level).
> >>>>>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice
> to
> >>>>>> have,
> >>>>>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if
> >> you
> >>>>>>>> take a
> >>>>>>>>> Map<String, String> as input you won here),
> >>>>>>>>> 3. Now you have to abstract the handler and make the default
> >> handler
> >>>> a
> >>>>>>>>> facade for user handlers. User handlers are CDI beans. I would
> >> start
> >>>> by
> >>>>>>>>> making them with something between servlet and jaxrs:
> >>>>>>>>>
> >>>>>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> >>>>>>>> Matching.EXACT)
> >>>>>>>>> method being the http method handled, url the urlpattern matched
> >>>> thanks
> >>>>>>>> the
> >>>>>>>>> matching algo (i used an enum but it can be anything equivalent).
> >>>> EXACT
> >>>>>>>>> means request path == url, we can envision wildcard matching (as
> in
> >>>>>>>>> servlet), regex matching etc...
> >>>>>>>>>
> >>>>>>>>> The signature can start to be the exact expected one
> >>>>>>>>> (CompletionStage<Response> onRequest(Request)) while validated in
> >> the
> >>>>>> cdi
> >>>>>>>>> extension grabbing the handlers, then you can relax the
> >>>> CompletionStage
> >>>>>>>>> requirement (Response onReq(Request)) and finally you can go
> closer
> >>>> to
> >>>>>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
> >>>> Request
> >>>>>>>> API
> >>>>>>>>> is nice enough it is not required in this layer - it can be a
> layer
> >>>> on
> >>>>>>>> top
> >>>>>>>>> as jaxrs is on top of servlet. What's important here is to be
> >>>> reactive
> >>>>>>>>> friendly by design - I'll let you play with the threading
> >> strategies
> >>>> to
> >>>>>>>>> have an useful CompletionStage and how to link it - or not ;) -
> to
> >>>>>> netty
> >>>>>>>>> executors.
> >>>>>>>>>
> >>>>>>>>> Once handlers well done, it is easy to add filters on top of it,
> >> same
> >>>>>>>> kind
> >>>>>>>>> of API but it takes another optional parameter:
> >>>>>>>>>
> >>>>>>>>> CompletionStage<Response> onRequest(Request request,
> >>>>>>>>> Supplier<CompletionStage<Response>> proceed);
> >>>>>>>>>
> >>>>>>>>> with proceed the call to filter N+1 and finally the handler
> (check
> >>>> out
> >>>>>>>> OWB
> >>>>>>>>> interceptor impl, it is exactly the same.
> >>>>>>>>>
> >>>>>>>>> Last important point: ensure to handle @Priority (or add
> priority =
> >>>> int
> >>>>>>>>> in @HttpHandler) cause when you will implement the matching chain
> >> you
> >>>>>>>> will
> >>>>>>>>> need an order normally.
> >>>>>>>>>
> >>>>>>>>> Bonus: you can make the matching strategies pluggable if you want
> >> and
> >>>>>>>> just
> >>>>>>>>> provide some defaults OOTB.
> >>>>>>>>>
> >>>>>>>>> Hope it makes sense.
> >>>>>>>>>
> >>>>>>>>> Romain Manni-Bucau
> >>>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>>>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>>>>>> https://github.com/rmannibucau> |
> >>>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>>>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
> >>>> fischer.a@mailbox.org>
> >>>>>> a
> >>>>>>>>> écrit :
> >>>>>>>>>
> >>>>>>>>>> Hello everyone,
> >>>>>>>>>>
> >>>>>>>>>> in the last month I have spent most of my time getting to know
> >>>> coding
> >>>>>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to
> know
> >>>> CDI
> >>>>>>>>>> extensions which will be the technological foundation for the
> >>>> server.
> >>>>>>>>>> Next up will be defining and implementing the HTTP API, which
> will
> >>>>>> bring
> >>>>>>>>>> CDI and Netty together. Feel free to contribute your thoughts on
> >> the
> >>>>>>>>>> matter here on the mailing list or in the respective Jira issue:
> >>>>>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>>>>>>>>>
> >>>>>>>>>> @Romain: can you share some ideas, annotations, interfaces for
> how
> >>>> you
> >>>>>>>>>> see the API roughly? Any kind of formal requirement-proposal
> would
> >>>> be
> >>>>>>>>>> helpful to start with.
> >>>>>>>>>>
> >>>>>>>>>> Thanks and best regards,
> >>>>>>>>>> Alexander
> >>>>>>>>>>
> >>>>>>>>>>
>

Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hi Romain,

thanks for the feedback. I made subtasks in Jira for the leftover server
features and marked them for later.
Regarding the configuration of our server, I took a look at how
Meecrowave's Builder does it. Do you think it's a good idea to adopt
this structure or should we build it another way?
And about the server as injectable bean: can you elaborate a bit about
how you intend to use it and how it would be an advantage for you? What
methods would you need available? Would it be like a container class
that should contain all application scoped info (e.g. our HttpHandlers,
the actual server)?

Thanks and best regards,
Alex

On 06.07.2020 17:36, Romain Manni-Bucau wrote:
> Hi Alex,
>
> A completionstage is just a promise so how it is wired is not that
> important - it is not rare i don't use the fluent API for example but a
> custom listener impl - but it is key to know in which thread context is it
> executed.
> Typically with your impl you inherit the caller threading - which can be
> what you want or not. Concretely, while it is NOT netty NIOLoop threads it
> is ok I think.
> A small issue you can hit is the full http response is not chunking
> compatible but it can be done in a second phase I guess.
> In terms of global arch, you will also want to preresolve (see it as a
> precompile phase) the execution (so no CDI.current().select(info.clazz).
> get() at runtime but a resolve during the bootstrap or lazily but only
> once). Same kind of side note for query params and form params, you likely
> want to parse them lazily and call the decoder.destroy() in a finally block
> ;).
> That said, the showcase is already nice and this is pretty much details
> since the structure is there and I guess it can be tackled after GSoC.
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le lun. 6 juil. 2020 à 17:03, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hey Romain,
>>
>> the API, Netty and CDI are roughly working together now.
>> How do you think we should handle the CompletionStage case in Netty?
>> Should we handle it in Netty's ChannelFuture features or leave it out of
>> there as CompletionStage does its work already?
>> Right now I went with using ChannelFuture for CompletionStage. You can
>> see the part here:
>>
>>
>> https://github.com/a-rekkusu/owb-centric-microserver/blob/master/impl/src/main/java/org/apache/peeco/impl/HttpServerHandler.java#L69
>>
>> Please let me know what you think overall. Next up would be the
>> configuration tasks (e.g. server as CDI bean).
>> Regarding the schedule, GSOC is running until August 31st, so Thomas and
>> I try to get started with the native part from next week onwards, as we
>> slowly hit the middle of the project time.
>>
>> Best regards,
>> Alex
>>
>> On 19.06.2020 16:49, Romain Manni-Bucau wrote:
>>> Except Response.setOutput which should use a plain InputStream (instead
>> of
>>> byte array flavor) it looks ok
>>>
>>> About parameters, one option is to do a "return
>>> Stream.concat(body.entrySet().stream(),
>>> form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
>>> Map.Entry::getValue, this::myMerger);" but impl is a detail for now ;).
>>> Another - once again not blocking to impl - small note is you rarely use
>>> body + param in the same request so it can be lazily instantiated (avoids
>>> the parsing - netty has the needed classes to parse them) so a Supplier
>> can
>>> makes sense too, but this would be in the optim phase.
>>>
>>> In other words I think you can do a first impl with that API, then see
>> how
>>> to handle chunking and then only optimize the api internals, at least it
>> is
>>> how I would proceed.
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>> <http://rmannibucau.wordpress.com> | Github <
>> https://github.com/rmannibucau> |
>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>
>>>
>>> Le ven. 19 juin 2020 à 15:53, Alexander Fischer <fi...@mailbox.org>
>> a
>>> écrit :
>>>
>>>> Hi Romain,
>>>>
>>>> you are right with your points and I've tried to apply them. The
>>>> Request.parameters() method might be solvable more elegantly. Only
>>>> streams were a bit unclear to me, but I did it as I understood it for
>>>> now (correct me if I got it wrong):
>>>> the user writes/casts his intended output to a ByteArrayInputStream,
>>>> which is handed over to netty that transforms it to its actual output
>>>> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
>>>> Let me know what you think of the current state, please. Once again the
>>>> repo link, just for convenience.
>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>
>>>> Thanks and best regards,
>>>> Alex
>>>>
>>>> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
>>>>> Should matching be an array? If so how would you impl it? (it is
>>>> associated
>>>>> with "url" or another parameter for its config, for instance EXACT +
>> path
>>>>> so i don't see how it would work to support EXACT and WILDCARD at the
>>>> same
>>>>> time for ex).
>>>>> In Request ensure to return Map<String, List<String>> and not
>>>>> HashMap<String, String> (it is not a hashmap cause headers are case
>>>>> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO
>> but
>>>>> no need to expose the impl).
>>>>> Parameters should likely be split in body parameters (form data) and
>>>> query
>>>>> parameters (so getParameter(String) would be a facade to 2 get in query
>>>> and
>>>>> form maps).
>>>>> Kind of the same remark on the response (for HashMap) + payload is an
>>>>> InputStream. This one requires some explanation:
>>>>>
>>>>> 1. Using a ByteArrayOutputStream is quite limiting since you drop all
>>>>> decorations and oversized payload support
>>>>> 2. An outputstream requires the server to know how to map this object
>> to
>>>>> something readable (input stream or the reactive equivalent)
>>>>> 3. output stream will likely require the server to inject the instance
>>>> once
>>>>> 1 is fixed which is something we should try to avoid
>>>>>
>>>>> Now if you move to an Inputstream you can consumer it easily from the
>>>>> server point of view, wrap it easily (in a filter for ex) and setting
>> the
>>>>> output is as easy:
>>>>>
>>>>> setOutput(new ByteArrayInputStream(...));
>>>>> + the user friendly flavor(s): setOutput(String) (which does the
>>>>> setoutput(inputStream) + setHeader(content-length))
>>>>>
>>>>> Romain Manni-Bucau
>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>> https://github.com/rmannibucau> |
>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>
>>>>> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fischer.a@mailbox.org
>>>> a
>>>>> écrit :
>>>>>
>>>>>> Hey Romain,
>>>>>>
>>>>>> thanks for the feedback! I have implemented the API feedback now,
>> please
>>>>>> take another look:
>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>>>
>>>>>> Are there functionalities that you miss?
>>>>>> Else, the Netty implementation ist next.
>>>>>>
>>>>>> Best regards,
>>>>>> Alex
>>>>>>
>>>>>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
>>>>>>> Hi Alex,
>>>>>>>
>>>>>>> I don't think you need the HttpHandler annotation to be a qualifier
>>>> (will
>>>>>>> typically end up on a method not producing any bean at some point I
>>>> think
>>>>>>> as in the example at the end of this answer).
>>>>>>> I guess Request/Response models are not yet done? Side note before
>> you
>>>>>> work
>>>>>>> on them: maybe don't copy servlet API, content-type, content-length
>> etc
>>>>>> are
>>>>>>> just headers, no need to make them specific, also prefer to set the
>>>>>> payload
>>>>>>> (as an inputstream or reactive stream) rather than encapsulating
>>>>>> read/write
>>>>>>> methods, it enables a better composition and decoration in general
>> and
>>>>>>> bypasses to go through a provider/factory to create
>> requests/responses.
>>>>>>> Last thing is you probably want to create a package for that work and
>>>> not
>>>>>>> use the default one ;).
>>>>>>>
>>>>>>> Typically it is a good start IMHO and once this works I'd do another
>>>>>> small
>>>>>>> iteration to end up on:
>>>>>>>
>>>>>>> public class HelloWorldHandlerFuture
>>>>>>> {
>>>>>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
>>>> "/hello",
>>>>>>> matching = Matching.EXACT)
>>>>>>> public CompletionStage<Response> apply(Request request)
>>>>>>> {
>>>>>>> return CompletableFuture.supplyAsync(() ->
>>>>>>> {
>>>>>>> Response response = new Response();
>>>>>>> response.setStatus(200);
>>>>>>> response.write("Hello World from " + getClass().getName());
>>>>>>> return response;
>>>>>>> });
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> Small side note (fully related to CompletionStage more than your
>>>> current
>>>>>>> work: if you want a synchronous impl of a CompletionStage you can use
>>>>>>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync -
>>>> and
>>>>>> if
>>>>>>> you want to be async (sypplyAsync) ensure you pass an executor as
>>>> second
>>>>>>> parameter otherwise you end up being in default ForkJoinPool which
>> has
>>>> a
>>>>>>> lot of side effects and limitations.
>>>>>>>
>>>>>>> Anyway, very good first iteration, it is pretty close to what I was
>>>>>>> envisioning and it looks as smooth as I was thinking.
>>>>>>>
>>>>>>> Small tip for the impl phase (don't know if it is the next one or
>> not):
>>>>>> for
>>>>>>> the handler registration, ensure to enable to do it programmatically:
>>>>>>> register(Function<Request, CompletionStage<Response>>). It will
>> enable
>>>> to
>>>>>>> use other models than the annotated one which is just a simplified
>> API
>>>> of
>>>>>>> the actual one the server uses internally.
>>>>>>>
>>>>>>> Romain Manni-Bucau
>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>>>> https://github.com/rmannibucau> |
>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <
>> fischer.a@mailbox.org
>>>>>> a
>>>>>>> écrit :
>>>>>>>
>>>>>>>> Hi Romain,
>>>>>>>>
>>>>>>>> I have made a first draft for the API and example showcase:
>>>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>>>>>
>>>>>>>> Please take a look and let me know what you think.
>>>>>>>> CompletionStage is supported, but right now for all requests on a
>>>>>>>> handler. If you would want a CompletableFuture only for POST for
>>>>>>>> example, and not on GET, how do you think we should handle that?
>>>>>>>> We could do it with a second HttpHandler on the same url but with
>> the
>>>>>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
>>>>>> HelloWorldHandlerPost).
>>>>>>>> Kind regards,
>>>>>>>> Alex
>>>>>>>>
>>>>>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
>>>>>>>>> Hi Alex,
>>>>>>>>>
>>>>>>>>> Nothing is written in the stone but here is how I would approach
>>>> that:
>>>>>>>>> 1. Write a HTTP server able to call a handler to answer a request -
>>>> you
>>>>>>>> can
>>>>>>>>> start by giving a hardcoded handler but in terms of design, ensure
>>>> you
>>>>>>>> get
>>>>>>>>> something taking a Request abstracting as input and a Response
>>>>>>>> abstraction
>>>>>>>>> as output.
>>>>>>>>> Netty has these abstraction but we don't want to depend on netty so
>>>> you
>>>>>>>>> should duplicate it making it even more user friendly (netty stays
>>>> low
>>>>>>>>> level).
>>>>>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice to
>>>>>> have,
>>>>>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if
>> you
>>>>>>>> take a
>>>>>>>>> Map<String, String> as input you won here),
>>>>>>>>> 3. Now you have to abstract the handler and make the default
>> handler
>>>> a
>>>>>>>>> facade for user handlers. User handlers are CDI beans. I would
>> start
>>>> by
>>>>>>>>> making them with something between servlet and jaxrs:
>>>>>>>>>
>>>>>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
>>>>>>>> Matching.EXACT)
>>>>>>>>> method being the http method handled, url the urlpattern matched
>>>> thanks
>>>>>>>> the
>>>>>>>>> matching algo (i used an enum but it can be anything equivalent).
>>>> EXACT
>>>>>>>>> means request path == url, we can envision wildcard matching (as in
>>>>>>>>> servlet), regex matching etc...
>>>>>>>>>
>>>>>>>>> The signature can start to be the exact expected one
>>>>>>>>> (CompletionStage<Response> onRequest(Request)) while validated in
>> the
>>>>>> cdi
>>>>>>>>> extension grabbing the handlers, then you can relax the
>>>> CompletionStage
>>>>>>>>> requirement (Response onReq(Request)) and finally you can go closer
>>>> to
>>>>>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
>>>> Request
>>>>>>>> API
>>>>>>>>> is nice enough it is not required in this layer - it can be a layer
>>>> on
>>>>>>>> top
>>>>>>>>> as jaxrs is on top of servlet. What's important here is to be
>>>> reactive
>>>>>>>>> friendly by design - I'll let you play with the threading
>> strategies
>>>> to
>>>>>>>>> have an useful CompletionStage and how to link it - or not ;) - to
>>>>>> netty
>>>>>>>>> executors.
>>>>>>>>>
>>>>>>>>> Once handlers well done, it is easy to add filters on top of it,
>> same
>>>>>>>> kind
>>>>>>>>> of API but it takes another optional parameter:
>>>>>>>>>
>>>>>>>>> CompletionStage<Response> onRequest(Request request,
>>>>>>>>> Supplier<CompletionStage<Response>> proceed);
>>>>>>>>>
>>>>>>>>> with proceed the call to filter N+1 and finally the handler (check
>>>> out
>>>>>>>> OWB
>>>>>>>>> interceptor impl, it is exactly the same.
>>>>>>>>>
>>>>>>>>> Last important point: ensure to handle @Priority (or add priority =
>>>> int
>>>>>>>>> in @HttpHandler) cause when you will implement the matching chain
>> you
>>>>>>>> will
>>>>>>>>> need an order normally.
>>>>>>>>>
>>>>>>>>> Bonus: you can make the matching strategies pluggable if you want
>> and
>>>>>>>> just
>>>>>>>>> provide some defaults OOTB.
>>>>>>>>>
>>>>>>>>> Hope it makes sense.
>>>>>>>>>
>>>>>>>>> Romain Manni-Bucau
>>>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>>>>>> https://github.com/rmannibucau> |
>>>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
>>>> fischer.a@mailbox.org>
>>>>>> a
>>>>>>>>> écrit :
>>>>>>>>>
>>>>>>>>>> Hello everyone,
>>>>>>>>>>
>>>>>>>>>> in the last month I have spent most of my time getting to know
>>>> coding
>>>>>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know
>>>> CDI
>>>>>>>>>> extensions which will be the technological foundation for the
>>>> server.
>>>>>>>>>> Next up will be defining and implementing the HTTP API, which will
>>>>>> bring
>>>>>>>>>> CDI and Netty together. Feel free to contribute your thoughts on
>> the
>>>>>>>>>> matter here on the mailing list or in the respective Jira issue:
>>>>>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>>>>>>>>>
>>>>>>>>>> @Romain: can you share some ideas, annotations, interfaces for how
>>>> you
>>>>>>>>>> see the API roughly? Any kind of formal requirement-proposal would
>>>> be
>>>>>>>>>> helpful to start with.
>>>>>>>>>>
>>>>>>>>>> Thanks and best regards,
>>>>>>>>>> Alexander
>>>>>>>>>>
>>>>>>>>>>

Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Alex,

A completionstage is just a promise so how it is wired is not that
important - it is not rare i don't use the fluent API for example but a
custom listener impl - but it is key to know in which thread context is it
executed.
Typically with your impl you inherit the caller threading - which can be
what you want or not. Concretely, while it is NOT netty NIOLoop threads it
is ok I think.
A small issue you can hit is the full http response is not chunking
compatible but it can be done in a second phase I guess.
In terms of global arch, you will also want to preresolve (see it as a
precompile phase) the execution (so no CDI.current().select(info.clazz).
get() at runtime but a resolve during the bootstrap or lazily but only
once). Same kind of side note for query params and form params, you likely
want to parse them lazily and call the decoder.destroy() in a finally block
;).
That said, the showcase is already nice and this is pretty much details
since the structure is there and I guess it can be tackled after GSoC.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le lun. 6 juil. 2020 à 17:03, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hey Romain,
>
> the API, Netty and CDI are roughly working together now.
> How do you think we should handle the CompletionStage case in Netty?
> Should we handle it in Netty's ChannelFuture features or leave it out of
> there as CompletionStage does its work already?
> Right now I went with using ChannelFuture for CompletionStage. You can
> see the part here:
>
>
> https://github.com/a-rekkusu/owb-centric-microserver/blob/master/impl/src/main/java/org/apache/peeco/impl/HttpServerHandler.java#L69
>
> Please let me know what you think overall. Next up would be the
> configuration tasks (e.g. server as CDI bean).
> Regarding the schedule, GSOC is running until August 31st, so Thomas and
> I try to get started with the native part from next week onwards, as we
> slowly hit the middle of the project time.
>
> Best regards,
> Alex
>
> On 19.06.2020 16:49, Romain Manni-Bucau wrote:
> > Except Response.setOutput which should use a plain InputStream (instead
> of
> > byte array flavor) it looks ok
> >
> > About parameters, one option is to do a "return
> > Stream.concat(body.entrySet().stream(),
> > form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
> > Map.Entry::getValue, this::myMerger);" but impl is a detail for now ;).
> > Another - once again not blocking to impl - small note is you rarely use
> > body + param in the same request so it can be lazily instantiated (avoids
> > the parsing - netty has the needed classes to parse them) so a Supplier
> can
> > makes sense too, but this would be in the optim phase.
> >
> > In other words I think you can do a first impl with that API, then see
> how
> > to handle chunking and then only optimize the api internals, at least it
> is
> > how I would proceed.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le ven. 19 juin 2020 à 15:53, Alexander Fischer <fi...@mailbox.org>
> a
> > écrit :
> >
> >> Hi Romain,
> >>
> >> you are right with your points and I've tried to apply them. The
> >> Request.parameters() method might be solvable more elegantly. Only
> >> streams were a bit unclear to me, but I did it as I understood it for
> >> now (correct me if I got it wrong):
> >> the user writes/casts his intended output to a ByteArrayInputStream,
> >> which is handed over to netty that transforms it to its actual output
> >> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
> >> Let me know what you think of the current state, please. Once again the
> >> repo link, just for convenience.
> >> https://github.com/a-rekkusu/owb-centric-microserver
> >>
> >> Thanks and best regards,
> >> Alex
> >>
> >> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
> >>> Should matching be an array? If so how would you impl it? (it is
> >> associated
> >>> with "url" or another parameter for its config, for instance EXACT +
> path
> >>> so i don't see how it would work to support EXACT and WILDCARD at the
> >> same
> >>> time for ex).
> >>> In Request ensure to return Map<String, List<String>> and not
> >>> HashMap<String, String> (it is not a hashmap cause headers are case
> >>> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO
> but
> >>> no need to expose the impl).
> >>> Parameters should likely be split in body parameters (form data) and
> >> query
> >>> parameters (so getParameter(String) would be a facade to 2 get in query
> >> and
> >>> form maps).
> >>> Kind of the same remark on the response (for HashMap) + payload is an
> >>> InputStream. This one requires some explanation:
> >>>
> >>> 1. Using a ByteArrayOutputStream is quite limiting since you drop all
> >>> decorations and oversized payload support
> >>> 2. An outputstream requires the server to know how to map this object
> to
> >>> something readable (input stream or the reactive equivalent)
> >>> 3. output stream will likely require the server to inject the instance
> >> once
> >>> 1 is fixed which is something we should try to avoid
> >>>
> >>> Now if you move to an Inputstream you can consumer it easily from the
> >>> server point of view, wrap it easily (in a filter for ex) and setting
> the
> >>> output is as easy:
> >>>
> >>> setOutput(new ByteArrayInputStream(...));
> >>> + the user friendly flavor(s): setOutput(String) (which does the
> >>> setoutput(inputStream) + setHeader(content-length))
> >>>
> >>> Romain Manni-Bucau
> >>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>
> >>>
> >>> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fischer.a@mailbox.org
> >
> >> a
> >>> écrit :
> >>>
> >>>> Hey Romain,
> >>>>
> >>>> thanks for the feedback! I have implemented the API feedback now,
> please
> >>>> take another look:
> >>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>
> >>>> Are there functionalities that you miss?
> >>>> Else, the Netty implementation ist next.
> >>>>
> >>>> Best regards,
> >>>> Alex
> >>>>
> >>>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> >>>>> Hi Alex,
> >>>>>
> >>>>> I don't think you need the HttpHandler annotation to be a qualifier
> >> (will
> >>>>> typically end up on a method not producing any bean at some point I
> >> think
> >>>>> as in the example at the end of this answer).
> >>>>> I guess Request/Response models are not yet done? Side note before
> you
> >>>> work
> >>>>> on them: maybe don't copy servlet API, content-type, content-length
> etc
> >>>> are
> >>>>> just headers, no need to make them specific, also prefer to set the
> >>>> payload
> >>>>> (as an inputstream or reactive stream) rather than encapsulating
> >>>> read/write
> >>>>> methods, it enables a better composition and decoration in general
> and
> >>>>> bypasses to go through a provider/factory to create
> requests/responses.
> >>>>> Last thing is you probably want to create a package for that work and
> >> not
> >>>>> use the default one ;).
> >>>>>
> >>>>> Typically it is a good start IMHO and once this works I'd do another
> >>>> small
> >>>>> iteration to end up on:
> >>>>>
> >>>>> public class HelloWorldHandlerFuture
> >>>>> {
> >>>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
> >> "/hello",
> >>>>> matching = Matching.EXACT)
> >>>>> public CompletionStage<Response> apply(Request request)
> >>>>> {
> >>>>> return CompletableFuture.supplyAsync(() ->
> >>>>> {
> >>>>> Response response = new Response();
> >>>>> response.setStatus(200);
> >>>>> response.write("Hello World from " + getClass().getName());
> >>>>> return response;
> >>>>> });
> >>>>> }
> >>>>> }
> >>>>>
> >>>>> Small side note (fully related to CompletionStage more than your
> >> current
> >>>>> work: if you want a synchronous impl of a CompletionStage you can use
> >>>>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync -
> >> and
> >>>> if
> >>>>> you want to be async (sypplyAsync) ensure you pass an executor as
> >> second
> >>>>> parameter otherwise you end up being in default ForkJoinPool which
> has
> >> a
> >>>>> lot of side effects and limitations.
> >>>>>
> >>>>> Anyway, very good first iteration, it is pretty close to what I was
> >>>>> envisioning and it looks as smooth as I was thinking.
> >>>>>
> >>>>> Small tip for the impl phase (don't know if it is the next one or
> not):
> >>>> for
> >>>>> the handler registration, ensure to enable to do it programmatically:
> >>>>> register(Function<Request, CompletionStage<Response>>). It will
> enable
> >> to
> >>>>> use other models than the annotated one which is just a simplified
> API
> >> of
> >>>>> the actual one the server uses internally.
> >>>>>
> >>>>> Romain Manni-Bucau
> >>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>> https://github.com/rmannibucau> |
> >>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>
> >>>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <
> fischer.a@mailbox.org
> >>>> a
> >>>>> écrit :
> >>>>>
> >>>>>> Hi Romain,
> >>>>>>
> >>>>>> I have made a first draft for the API and example showcase:
> >>>>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>>>
> >>>>>> Please take a look and let me know what you think.
> >>>>>> CompletionStage is supported, but right now for all requests on a
> >>>>>> handler. If you would want a CompletableFuture only for POST for
> >>>>>> example, and not on GET, how do you think we should handle that?
> >>>>>> We could do it with a second HttpHandler on the same url but with
> the
> >>>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
> >>>> HelloWorldHandlerPost).
> >>>>>> Kind regards,
> >>>>>> Alex
> >>>>>>
> >>>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> >>>>>>> Hi Alex,
> >>>>>>>
> >>>>>>> Nothing is written in the stone but here is how I would approach
> >> that:
> >>>>>>> 1. Write a HTTP server able to call a handler to answer a request -
> >> you
> >>>>>> can
> >>>>>>> start by giving a hardcoded handler but in terms of design, ensure
> >> you
> >>>>>> get
> >>>>>>> something taking a Request abstracting as input and a Response
> >>>>>> abstraction
> >>>>>>> as output.
> >>>>>>> Netty has these abstraction but we don't want to depend on netty so
> >> you
> >>>>>>> should duplicate it making it even more user friendly (netty stays
> >> low
> >>>>>>> level).
> >>>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice to
> >>>> have,
> >>>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if
> you
> >>>>>> take a
> >>>>>>> Map<String, String> as input you won here),
> >>>>>>> 3. Now you have to abstract the handler and make the default
> handler
> >> a
> >>>>>>> facade for user handlers. User handlers are CDI beans. I would
> start
> >> by
> >>>>>>> making them with something between servlet and jaxrs:
> >>>>>>>
> >>>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> >>>>>> Matching.EXACT)
> >>>>>>> method being the http method handled, url the urlpattern matched
> >> thanks
> >>>>>> the
> >>>>>>> matching algo (i used an enum but it can be anything equivalent).
> >> EXACT
> >>>>>>> means request path == url, we can envision wildcard matching (as in
> >>>>>>> servlet), regex matching etc...
> >>>>>>>
> >>>>>>> The signature can start to be the exact expected one
> >>>>>>> (CompletionStage<Response> onRequest(Request)) while validated in
> the
> >>>> cdi
> >>>>>>> extension grabbing the handlers, then you can relax the
> >> CompletionStage
> >>>>>>> requirement (Response onReq(Request)) and finally you can go closer
> >> to
> >>>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
> >> Request
> >>>>>> API
> >>>>>>> is nice enough it is not required in this layer - it can be a layer
> >> on
> >>>>>> top
> >>>>>>> as jaxrs is on top of servlet. What's important here is to be
> >> reactive
> >>>>>>> friendly by design - I'll let you play with the threading
> strategies
> >> to
> >>>>>>> have an useful CompletionStage and how to link it - or not ;) - to
> >>>> netty
> >>>>>>> executors.
> >>>>>>>
> >>>>>>> Once handlers well done, it is easy to add filters on top of it,
> same
> >>>>>> kind
> >>>>>>> of API but it takes another optional parameter:
> >>>>>>>
> >>>>>>> CompletionStage<Response> onRequest(Request request,
> >>>>>>> Supplier<CompletionStage<Response>> proceed);
> >>>>>>>
> >>>>>>> with proceed the call to filter N+1 and finally the handler (check
> >> out
> >>>>>> OWB
> >>>>>>> interceptor impl, it is exactly the same.
> >>>>>>>
> >>>>>>> Last important point: ensure to handle @Priority (or add priority =
> >> int
> >>>>>>> in @HttpHandler) cause when you will implement the matching chain
> you
> >>>>>> will
> >>>>>>> need an order normally.
> >>>>>>>
> >>>>>>> Bonus: you can make the matching strategies pluggable if you want
> and
> >>>>>> just
> >>>>>>> provide some defaults OOTB.
> >>>>>>>
> >>>>>>> Hope it makes sense.
> >>>>>>>
> >>>>>>> Romain Manni-Bucau
> >>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>>>> https://github.com/rmannibucau> |
> >>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
> >> fischer.a@mailbox.org>
> >>>> a
> >>>>>>> écrit :
> >>>>>>>
> >>>>>>>> Hello everyone,
> >>>>>>>>
> >>>>>>>> in the last month I have spent most of my time getting to know
> >> coding
> >>>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know
> >> CDI
> >>>>>>>> extensions which will be the technological foundation for the
> >> server.
> >>>>>>>> Next up will be defining and implementing the HTTP API, which will
> >>>> bring
> >>>>>>>> CDI and Netty together. Feel free to contribute your thoughts on
> the
> >>>>>>>> matter here on the mailing list or in the respective Jira issue:
> >>>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>>>>>>>
> >>>>>>>> @Romain: can you share some ideas, annotations, interfaces for how
> >> you
> >>>>>>>> see the API roughly? Any kind of formal requirement-proposal would
> >> be
> >>>>>>>> helpful to start with.
> >>>>>>>>
> >>>>>>>> Thanks and best regards,
> >>>>>>>> Alexander
> >>>>>>>>
> >>>>>>>>
>

Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hey Romain,

the API, Netty and CDI are roughly working together now.
How do you think we should handle the CompletionStage case in Netty?
Should we handle it in Netty's ChannelFuture features or leave it out of
there as CompletionStage does its work already?
Right now I went with using ChannelFuture for CompletionStage. You can
see the part here:

https://github.com/a-rekkusu/owb-centric-microserver/blob/master/impl/src/main/java/org/apache/peeco/impl/HttpServerHandler.java#L69

Please let me know what you think overall. Next up would be the
configuration tasks (e.g. server as CDI bean).
Regarding the schedule, GSOC is running until August 31st, so Thomas and
I try to get started with the native part from next week onwards, as we
slowly hit the middle of the project time.

Best regards,
Alex

On 19.06.2020 16:49, Romain Manni-Bucau wrote:
> Except Response.setOutput which should use a plain InputStream (instead of
> byte array flavor) it looks ok
>
> About parameters, one option is to do a "return
> Stream.concat(body.entrySet().stream(),
> form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
> Map.Entry::getValue, this::myMerger);" but impl is a detail for now ;).
> Another - once again not blocking to impl - small note is you rarely use
> body + param in the same request so it can be lazily instantiated (avoids
> the parsing - netty has the needed classes to parse them) so a Supplier can
> makes sense too, but this would be in the optim phase.
>
> In other words I think you can do a first impl with that API, then see how
> to handle chunking and then only optimize the api internals, at least it is
> how I would proceed.
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le ven. 19 juin 2020 à 15:53, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hi Romain,
>>
>> you are right with your points and I've tried to apply them. The
>> Request.parameters() method might be solvable more elegantly. Only
>> streams were a bit unclear to me, but I did it as I understood it for
>> now (correct me if I got it wrong):
>> the user writes/casts his intended output to a ByteArrayInputStream,
>> which is handed over to netty that transforms it to its actual output
>> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
>> Let me know what you think of the current state, please. Once again the
>> repo link, just for convenience.
>> https://github.com/a-rekkusu/owb-centric-microserver
>>
>> Thanks and best regards,
>> Alex
>>
>> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
>>> Should matching be an array? If so how would you impl it? (it is
>> associated
>>> with "url" or another parameter for its config, for instance EXACT + path
>>> so i don't see how it would work to support EXACT and WILDCARD at the
>> same
>>> time for ex).
>>> In Request ensure to return Map<String, List<String>> and not
>>> HashMap<String, String> (it is not a hashmap cause headers are case
>>> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO but
>>> no need to expose the impl).
>>> Parameters should likely be split in body parameters (form data) and
>> query
>>> parameters (so getParameter(String) would be a facade to 2 get in query
>> and
>>> form maps).
>>> Kind of the same remark on the response (for HashMap) + payload is an
>>> InputStream. This one requires some explanation:
>>>
>>> 1. Using a ByteArrayOutputStream is quite limiting since you drop all
>>> decorations and oversized payload support
>>> 2. An outputstream requires the server to know how to map this object to
>>> something readable (input stream or the reactive equivalent)
>>> 3. output stream will likely require the server to inject the instance
>> once
>>> 1 is fixed which is something we should try to avoid
>>>
>>> Now if you move to an Inputstream you can consumer it easily from the
>>> server point of view, wrap it easily (in a filter for ex) and setting the
>>> output is as easy:
>>>
>>> setOutput(new ByteArrayInputStream(...));
>>> + the user friendly flavor(s): setOutput(String) (which does the
>>> setoutput(inputStream) + setHeader(content-length))
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>> <http://rmannibucau.wordpress.com> | Github <
>> https://github.com/rmannibucau> |
>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>
>>>
>>> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fi...@mailbox.org>
>> a
>>> écrit :
>>>
>>>> Hey Romain,
>>>>
>>>> thanks for the feedback! I have implemented the API feedback now, please
>>>> take another look:
>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>
>>>> Are there functionalities that you miss?
>>>> Else, the Netty implementation ist next.
>>>>
>>>> Best regards,
>>>> Alex
>>>>
>>>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
>>>>> Hi Alex,
>>>>>
>>>>> I don't think you need the HttpHandler annotation to be a qualifier
>> (will
>>>>> typically end up on a method not producing any bean at some point I
>> think
>>>>> as in the example at the end of this answer).
>>>>> I guess Request/Response models are not yet done? Side note before you
>>>> work
>>>>> on them: maybe don't copy servlet API, content-type, content-length etc
>>>> are
>>>>> just headers, no need to make them specific, also prefer to set the
>>>> payload
>>>>> (as an inputstream or reactive stream) rather than encapsulating
>>>> read/write
>>>>> methods, it enables a better composition and decoration in general and
>>>>> bypasses to go through a provider/factory to create requests/responses.
>>>>> Last thing is you probably want to create a package for that work and
>> not
>>>>> use the default one ;).
>>>>>
>>>>> Typically it is a good start IMHO and once this works I'd do another
>>>> small
>>>>> iteration to end up on:
>>>>>
>>>>> public class HelloWorldHandlerFuture
>>>>> {
>>>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
>> "/hello",
>>>>> matching = Matching.EXACT)
>>>>> public CompletionStage<Response> apply(Request request)
>>>>> {
>>>>> return CompletableFuture.supplyAsync(() ->
>>>>> {
>>>>> Response response = new Response();
>>>>> response.setStatus(200);
>>>>> response.write("Hello World from " + getClass().getName());
>>>>> return response;
>>>>> });
>>>>> }
>>>>> }
>>>>>
>>>>> Small side note (fully related to CompletionStage more than your
>> current
>>>>> work: if you want a synchronous impl of a CompletionStage you can use
>>>>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync -
>> and
>>>> if
>>>>> you want to be async (sypplyAsync) ensure you pass an executor as
>> second
>>>>> parameter otherwise you end up being in default ForkJoinPool which has
>> a
>>>>> lot of side effects and limitations.
>>>>>
>>>>> Anyway, very good first iteration, it is pretty close to what I was
>>>>> envisioning and it looks as smooth as I was thinking.
>>>>>
>>>>> Small tip for the impl phase (don't know if it is the next one or not):
>>>> for
>>>>> the handler registration, ensure to enable to do it programmatically:
>>>>> register(Function<Request, CompletionStage<Response>>). It will enable
>> to
>>>>> use other models than the annotated one which is just a simplified API
>> of
>>>>> the actual one the server uses internally.
>>>>>
>>>>> Romain Manni-Bucau
>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>> https://github.com/rmannibucau> |
>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>
>>>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fischer.a@mailbox.org
>>>> a
>>>>> écrit :
>>>>>
>>>>>> Hi Romain,
>>>>>>
>>>>>> I have made a first draft for the API and example showcase:
>>>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>>>
>>>>>> Please take a look and let me know what you think.
>>>>>> CompletionStage is supported, but right now for all requests on a
>>>>>> handler. If you would want a CompletableFuture only for POST for
>>>>>> example, and not on GET, how do you think we should handle that?
>>>>>> We could do it with a second HttpHandler on the same url but with the
>>>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
>>>> HelloWorldHandlerPost).
>>>>>> Kind regards,
>>>>>> Alex
>>>>>>
>>>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
>>>>>>> Hi Alex,
>>>>>>>
>>>>>>> Nothing is written in the stone but here is how I would approach
>> that:
>>>>>>> 1. Write a HTTP server able to call a handler to answer a request -
>> you
>>>>>> can
>>>>>>> start by giving a hardcoded handler but in terms of design, ensure
>> you
>>>>>> get
>>>>>>> something taking a Request abstracting as input and a Response
>>>>>> abstraction
>>>>>>> as output.
>>>>>>> Netty has these abstraction but we don't want to depend on netty so
>> you
>>>>>>> should duplicate it making it even more user friendly (netty stays
>> low
>>>>>>> level).
>>>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice to
>>>> have,
>>>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if you
>>>>>> take a
>>>>>>> Map<String, String> as input you won here),
>>>>>>> 3. Now you have to abstract the handler and make the default handler
>> a
>>>>>>> facade for user handlers. User handlers are CDI beans. I would start
>> by
>>>>>>> making them with something between servlet and jaxrs:
>>>>>>>
>>>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
>>>>>> Matching.EXACT)
>>>>>>> method being the http method handled, url the urlpattern matched
>> thanks
>>>>>> the
>>>>>>> matching algo (i used an enum but it can be anything equivalent).
>> EXACT
>>>>>>> means request path == url, we can envision wildcard matching (as in
>>>>>>> servlet), regex matching etc...
>>>>>>>
>>>>>>> The signature can start to be the exact expected one
>>>>>>> (CompletionStage<Response> onRequest(Request)) while validated in the
>>>> cdi
>>>>>>> extension grabbing the handlers, then you can relax the
>> CompletionStage
>>>>>>> requirement (Response onReq(Request)) and finally you can go closer
>> to
>>>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
>> Request
>>>>>> API
>>>>>>> is nice enough it is not required in this layer - it can be a layer
>> on
>>>>>> top
>>>>>>> as jaxrs is on top of servlet. What's important here is to be
>> reactive
>>>>>>> friendly by design - I'll let you play with the threading strategies
>> to
>>>>>>> have an useful CompletionStage and how to link it - or not ;) - to
>>>> netty
>>>>>>> executors.
>>>>>>>
>>>>>>> Once handlers well done, it is easy to add filters on top of it, same
>>>>>> kind
>>>>>>> of API but it takes another optional parameter:
>>>>>>>
>>>>>>> CompletionStage<Response> onRequest(Request request,
>>>>>>> Supplier<CompletionStage<Response>> proceed);
>>>>>>>
>>>>>>> with proceed the call to filter N+1 and finally the handler (check
>> out
>>>>>> OWB
>>>>>>> interceptor impl, it is exactly the same.
>>>>>>>
>>>>>>> Last important point: ensure to handle @Priority (or add priority =
>> int
>>>>>>> in @HttpHandler) cause when you will implement the matching chain you
>>>>>> will
>>>>>>> need an order normally.
>>>>>>>
>>>>>>> Bonus: you can make the matching strategies pluggable if you want and
>>>>>> just
>>>>>>> provide some defaults OOTB.
>>>>>>>
>>>>>>> Hope it makes sense.
>>>>>>>
>>>>>>> Romain Manni-Bucau
>>>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>>>> https://github.com/rmannibucau> |
>>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
>> fischer.a@mailbox.org>
>>>> a
>>>>>>> écrit :
>>>>>>>
>>>>>>>> Hello everyone,
>>>>>>>>
>>>>>>>> in the last month I have spent most of my time getting to know
>> coding
>>>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know
>> CDI
>>>>>>>> extensions which will be the technological foundation for the
>> server.
>>>>>>>> Next up will be defining and implementing the HTTP API, which will
>>>> bring
>>>>>>>> CDI and Netty together. Feel free to contribute your thoughts on the
>>>>>>>> matter here on the mailing list or in the respective Jira issue:
>>>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>>>>>>>
>>>>>>>> @Romain: can you share some ideas, annotations, interfaces for how
>> you
>>>>>>>> see the API roughly? Any kind of formal requirement-proposal would
>> be
>>>>>>>> helpful to start with.
>>>>>>>>
>>>>>>>> Thanks and best regards,
>>>>>>>> Alexander
>>>>>>>>
>>>>>>>>

Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Except Response.setOutput which should use a plain InputStream (instead of
byte array flavor) it looks ok

About parameters, one option is to do a "return
Stream.concat(body.entrySet().stream(),
form.entrySet().stream()).collect(toMap(Map.Entry::getKey,
Map.Entry::getValue, this::myMerger);" but impl is a detail for now ;).
Another - once again not blocking to impl - small note is you rarely use
body + param in the same request so it can be lazily instantiated (avoids
the parsing - netty has the needed classes to parse them) so a Supplier can
makes sense too, but this would be in the optim phase.

In other words I think you can do a first impl with that API, then see how
to handle chunking and then only optimize the api internals, at least it is
how I would proceed.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le ven. 19 juin 2020 à 15:53, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hi Romain,
>
> you are right with your points and I've tried to apply them. The
> Request.parameters() method might be solvable more elegantly. Only
> streams were a bit unclear to me, but I did it as I understood it for
> now (correct me if I got it wrong):
> the user writes/casts his intended output to a ByteArrayInputStream,
> which is handed over to netty that transforms it to its actual output
> (maybe ChannelBufferOutputStream, but I have yet to figure it out).
> Let me know what you think of the current state, please. Once again the
> repo link, just for convenience.
> https://github.com/a-rekkusu/owb-centric-microserver
>
> Thanks and best regards,
> Alex
>
> On 18.06.2020 15:26, Romain Manni-Bucau wrote:
> > Should matching be an array? If so how would you impl it? (it is
> associated
> > with "url" or another parameter for its config, for instance EXACT + path
> > so i don't see how it would work to support EXACT and WILDCARD at the
> same
> > time for ex).
> > In Request ensure to return Map<String, List<String>> and not
> > HashMap<String, String> (it is not a hashmap cause headers are case
> > insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO but
> > no need to expose the impl).
> > Parameters should likely be split in body parameters (form data) and
> query
> > parameters (so getParameter(String) would be a facade to 2 get in query
> and
> > form maps).
> > Kind of the same remark on the response (for HashMap) + payload is an
> > InputStream. This one requires some explanation:
> >
> > 1. Using a ByteArrayOutputStream is quite limiting since you drop all
> > decorations and oversized payload support
> > 2. An outputstream requires the server to know how to map this object to
> > something readable (input stream or the reactive equivalent)
> > 3. output stream will likely require the server to inject the instance
> once
> > 1 is fixed which is something we should try to avoid
> >
> > Now if you move to an Inputstream you can consumer it easily from the
> > server point of view, wrap it easily (in a filter for ex) and setting the
> > output is as easy:
> >
> > setOutput(new ByteArrayInputStream(...));
> > + the user friendly flavor(s): setOutput(String) (which does the
> > setoutput(inputStream) + setHeader(content-length))
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fi...@mailbox.org>
> a
> > écrit :
> >
> >> Hey Romain,
> >>
> >> thanks for the feedback! I have implemented the API feedback now, please
> >> take another look:
> >> https://github.com/a-rekkusu/owb-centric-microserver
> >>
> >> Are there functionalities that you miss?
> >> Else, the Netty implementation ist next.
> >>
> >> Best regards,
> >> Alex
> >>
> >> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> >>> Hi Alex,
> >>>
> >>> I don't think you need the HttpHandler annotation to be a qualifier
> (will
> >>> typically end up on a method not producing any bean at some point I
> think
> >>> as in the example at the end of this answer).
> >>> I guess Request/Response models are not yet done? Side note before you
> >> work
> >>> on them: maybe don't copy servlet API, content-type, content-length etc
> >> are
> >>> just headers, no need to make them specific, also prefer to set the
> >> payload
> >>> (as an inputstream or reactive stream) rather than encapsulating
> >> read/write
> >>> methods, it enables a better composition and decoration in general and
> >>> bypasses to go through a provider/factory to create requests/responses.
> >>> Last thing is you probably want to create a package for that work and
> not
> >>> use the default one ;).
> >>>
> >>> Typically it is a good start IMHO and once this works I'd do another
> >> small
> >>> iteration to end up on:
> >>>
> >>> public class HelloWorldHandlerFuture
> >>> {
> >>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url =
> "/hello",
> >>> matching = Matching.EXACT)
> >>> public CompletionStage<Response> apply(Request request)
> >>> {
> >>> return CompletableFuture.supplyAsync(() ->
> >>> {
> >>> Response response = new Response();
> >>> response.setStatus(200);
> >>> response.write("Hello World from " + getClass().getName());
> >>> return response;
> >>> });
> >>> }
> >>> }
> >>>
> >>> Small side note (fully related to CompletionStage more than your
> current
> >>> work: if you want a synchronous impl of a CompletionStage you can use
> >>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync -
> and
> >> if
> >>> you want to be async (sypplyAsync) ensure you pass an executor as
> second
> >>> parameter otherwise you end up being in default ForkJoinPool which has
> a
> >>> lot of side effects and limitations.
> >>>
> >>> Anyway, very good first iteration, it is pretty close to what I was
> >>> envisioning and it looks as smooth as I was thinking.
> >>>
> >>> Small tip for the impl phase (don't know if it is the next one or not):
> >> for
> >>> the handler registration, ensure to enable to do it programmatically:
> >>> register(Function<Request, CompletionStage<Response>>). It will enable
> to
> >>> use other models than the annotated one which is just a simplified API
> of
> >>> the actual one the server uses internally.
> >>>
> >>> Romain Manni-Bucau
> >>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>
> >>>
> >>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fischer.a@mailbox.org
> >
> >> a
> >>> écrit :
> >>>
> >>>> Hi Romain,
> >>>>
> >>>> I have made a first draft for the API and example showcase:
> >>>> https://github.com/a-rekkusu/owb-centric-microserver
> >>>>
> >>>> Please take a look and let me know what you think.
> >>>> CompletionStage is supported, but right now for all requests on a
> >>>> handler. If you would want a CompletableFuture only for POST for
> >>>> example, and not on GET, how do you think we should handle that?
> >>>> We could do it with a second HttpHandler on the same url but with the
> >>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
> >> HelloWorldHandlerPost).
> >>>> Kind regards,
> >>>> Alex
> >>>>
> >>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> >>>>> Hi Alex,
> >>>>>
> >>>>> Nothing is written in the stone but here is how I would approach
> that:
> >>>>>
> >>>>> 1. Write a HTTP server able to call a handler to answer a request -
> you
> >>>> can
> >>>>> start by giving a hardcoded handler but in terms of design, ensure
> you
> >>>> get
> >>>>> something taking a Request abstracting as input and a Response
> >>>> abstraction
> >>>>> as output.
> >>>>> Netty has these abstraction but we don't want to depend on netty so
> you
> >>>>> should duplicate it making it even more user friendly (netty stays
> low
> >>>>> level).
> >>>>> 2. Make this server CDI friendly, basically a CDI bean and nice to
> >> have,
> >>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if you
> >>>> take a
> >>>>> Map<String, String> as input you won here),
> >>>>> 3. Now you have to abstract the handler and make the default handler
> a
> >>>>> facade for user handlers. User handlers are CDI beans. I would start
> by
> >>>>> making them with something between servlet and jaxrs:
> >>>>>
> >>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> >>>> Matching.EXACT)
> >>>>> method being the http method handled, url the urlpattern matched
> thanks
> >>>> the
> >>>>> matching algo (i used an enum but it can be anything equivalent).
> EXACT
> >>>>> means request path == url, we can envision wildcard matching (as in
> >>>>> servlet), regex matching etc...
> >>>>>
> >>>>> The signature can start to be the exact expected one
> >>>>> (CompletionStage<Response> onRequest(Request)) while validated in the
> >> cdi
> >>>>> extension grabbing the handlers, then you can relax the
> CompletionStage
> >>>>> requirement (Response onReq(Request)) and finally you can go closer
> to
> >>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if
> Request
> >>>> API
> >>>>> is nice enough it is not required in this layer - it can be a layer
> on
> >>>> top
> >>>>> as jaxrs is on top of servlet. What's important here is to be
> reactive
> >>>>> friendly by design - I'll let you play with the threading strategies
> to
> >>>>> have an useful CompletionStage and how to link it - or not ;) - to
> >> netty
> >>>>> executors.
> >>>>>
> >>>>> Once handlers well done, it is easy to add filters on top of it, same
> >>>> kind
> >>>>> of API but it takes another optional parameter:
> >>>>>
> >>>>> CompletionStage<Response> onRequest(Request request,
> >>>>> Supplier<CompletionStage<Response>> proceed);
> >>>>>
> >>>>> with proceed the call to filter N+1 and finally the handler (check
> out
> >>>> OWB
> >>>>> interceptor impl, it is exactly the same.
> >>>>>
> >>>>> Last important point: ensure to handle @Priority (or add priority =
> int
> >>>>> in @HttpHandler) cause when you will implement the matching chain you
> >>>> will
> >>>>> need an order normally.
> >>>>>
> >>>>> Bonus: you can make the matching strategies pluggable if you want and
> >>>> just
> >>>>> provide some defaults OOTB.
> >>>>>
> >>>>> Hope it makes sense.
> >>>>>
> >>>>> Romain Manni-Bucau
> >>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>>>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>>>> <http://rmannibucau.wordpress.com> | Github <
> >>>> https://github.com/rmannibucau> |
> >>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>>>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>>>
> >>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <
> fischer.a@mailbox.org>
> >> a
> >>>>> écrit :
> >>>>>
> >>>>>> Hello everyone,
> >>>>>>
> >>>>>> in the last month I have spent most of my time getting to know
> coding
> >>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know
> CDI
> >>>>>> extensions which will be the technological foundation for the
> server.
> >>>>>>
> >>>>>> Next up will be defining and implementing the HTTP API, which will
> >> bring
> >>>>>> CDI and Netty together. Feel free to contribute your thoughts on the
> >>>>>> matter here on the mailing list or in the respective Jira issue:
> >>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>>>>>
> >>>>>> @Romain: can you share some ideas, annotations, interfaces for how
> you
> >>>>>> see the API roughly? Any kind of formal requirement-proposal would
> be
> >>>>>> helpful to start with.
> >>>>>>
> >>>>>> Thanks and best regards,
> >>>>>> Alexander
> >>>>>>
> >>>>>>
>

Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hi Romain,

you are right with your points and I've tried to apply them. The
Request.parameters() method might be solvable more elegantly. Only
streams were a bit unclear to me, but I did it as I understood it for
now (correct me if I got it wrong):
the user writes/casts his intended output to a ByteArrayInputStream,
which is handed over to netty that transforms it to its actual output
(maybe ChannelBufferOutputStream, but I have yet to figure it out).
Let me know what you think of the current state, please. Once again the
repo link, just for convenience.
https://github.com/a-rekkusu/owb-centric-microserver

Thanks and best regards,
Alex

On 18.06.2020 15:26, Romain Manni-Bucau wrote:
> Should matching be an array? If so how would you impl it? (it is associated
> with "url" or another parameter for its config, for instance EXACT + path
> so i don't see how it would work to support EXACT and WILDCARD at the same
> time for ex).
> In Request ensure to return Map<String, List<String>> and not
> HashMap<String, String> (it is not a hashmap cause headers are case
> insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO but
> no need to expose the impl).
> Parameters should likely be split in body parameters (form data) and query
> parameters (so getParameter(String) would be a facade to 2 get in query and
> form maps).
> Kind of the same remark on the response (for HashMap) + payload is an
> InputStream. This one requires some explanation:
>
> 1. Using a ByteArrayOutputStream is quite limiting since you drop all
> decorations and oversized payload support
> 2. An outputstream requires the server to know how to map this object to
> something readable (input stream or the reactive equivalent)
> 3. output stream will likely require the server to inject the instance once
> 1 is fixed which is something we should try to avoid
>
> Now if you move to an Inputstream you can consumer it easily from the
> server point of view, wrap it easily (in a filter for ex) and setting the
> output is as easy:
>
> setOutput(new ByteArrayInputStream(...));
> + the user friendly flavor(s): setOutput(String) (which does the
> setoutput(inputStream) + setHeader(content-length))
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hey Romain,
>>
>> thanks for the feedback! I have implemented the API feedback now, please
>> take another look:
>> https://github.com/a-rekkusu/owb-centric-microserver
>>
>> Are there functionalities that you miss?
>> Else, the Netty implementation ist next.
>>
>> Best regards,
>> Alex
>>
>> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
>>> Hi Alex,
>>>
>>> I don't think you need the HttpHandler annotation to be a qualifier (will
>>> typically end up on a method not producing any bean at some point I think
>>> as in the example at the end of this answer).
>>> I guess Request/Response models are not yet done? Side note before you
>> work
>>> on them: maybe don't copy servlet API, content-type, content-length etc
>> are
>>> just headers, no need to make them specific, also prefer to set the
>> payload
>>> (as an inputstream or reactive stream) rather than encapsulating
>> read/write
>>> methods, it enables a better composition and decoration in general and
>>> bypasses to go through a provider/factory to create requests/responses.
>>> Last thing is you probably want to create a package for that work and not
>>> use the default one ;).
>>>
>>> Typically it is a good start IMHO and once this works I'd do another
>> small
>>> iteration to end up on:
>>>
>>> public class HelloWorldHandlerFuture
>>> {
>>> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url = "/hello",
>>> matching = Matching.EXACT)
>>> public CompletionStage<Response> apply(Request request)
>>> {
>>> return CompletableFuture.supplyAsync(() ->
>>> {
>>> Response response = new Response();
>>> response.setStatus(200);
>>> response.write("Hello World from " + getClass().getName());
>>> return response;
>>> });
>>> }
>>> }
>>>
>>> Small side note (fully related to CompletionStage more than your current
>>> work: if you want a synchronous impl of a CompletionStage you can use
>>> CompletionFuture.completedFuture(response) - avoid the sypplyAsync - and
>> if
>>> you want to be async (sypplyAsync) ensure you pass an executor as second
>>> parameter otherwise you end up being in default ForkJoinPool which has a
>>> lot of side effects and limitations.
>>>
>>> Anyway, very good first iteration, it is pretty close to what I was
>>> envisioning and it looks as smooth as I was thinking.
>>>
>>> Small tip for the impl phase (don't know if it is the next one or not):
>> for
>>> the handler registration, ensure to enable to do it programmatically:
>>> register(Function<Request, CompletionStage<Response>>). It will enable to
>>> use other models than the annotated one which is just a simplified API of
>>> the actual one the server uses internally.
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>> <http://rmannibucau.wordpress.com> | Github <
>> https://github.com/rmannibucau> |
>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>
>>>
>>> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fi...@mailbox.org>
>> a
>>> écrit :
>>>
>>>> Hi Romain,
>>>>
>>>> I have made a first draft for the API and example showcase:
>>>> https://github.com/a-rekkusu/owb-centric-microserver
>>>>
>>>> Please take a look and let me know what you think.
>>>> CompletionStage is supported, but right now for all requests on a
>>>> handler. If you would want a CompletableFuture only for POST for
>>>> example, and not on GET, how do you think we should handle that?
>>>> We could do it with a second HttpHandler on the same url but with the
>>>> respective HttpMethod (e. g. HelloWorldHandlerGet /
>> HelloWorldHandlerPost).
>>>> Kind regards,
>>>> Alex
>>>>
>>>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
>>>>> Hi Alex,
>>>>>
>>>>> Nothing is written in the stone but here is how I would approach that:
>>>>>
>>>>> 1. Write a HTTP server able to call a handler to answer a request - you
>>>> can
>>>>> start by giving a hardcoded handler but in terms of design, ensure you
>>>> get
>>>>> something taking a Request abstracting as input and a Response
>>>> abstraction
>>>>> as output.
>>>>> Netty has these abstraction but we don't want to depend on netty so you
>>>>> should duplicate it making it even more user friendly (netty stays low
>>>>> level).
>>>>> 2. Make this server CDI friendly, basically a CDI bean and nice to
>> have,
>>>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if you
>>>> take a
>>>>> Map<String, String> as input you won here),
>>>>> 3. Now you have to abstract the handler and make the default handler a
>>>>> facade for user handlers. User handlers are CDI beans. I would start by
>>>>> making them with something between servlet and jaxrs:
>>>>>
>>>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
>>>> Matching.EXACT)
>>>>> method being the http method handled, url the urlpattern matched thanks
>>>> the
>>>>> matching algo (i used an enum but it can be anything equivalent). EXACT
>>>>> means request path == url, we can envision wildcard matching (as in
>>>>> servlet), regex matching etc...
>>>>>
>>>>> The signature can start to be the exact expected one
>>>>> (CompletionStage<Response> onRequest(Request)) while validated in the
>> cdi
>>>>> extension grabbing the handlers, then you can relax the CompletionStage
>>>>> requirement (Response onReq(Request)) and finally you can go closer to
>>>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if Request
>>>> API
>>>>> is nice enough it is not required in this layer - it can be a layer on
>>>> top
>>>>> as jaxrs is on top of servlet. What's important here is to be reactive
>>>>> friendly by design - I'll let you play with the threading strategies to
>>>>> have an useful CompletionStage and how to link it - or not ;) - to
>> netty
>>>>> executors.
>>>>>
>>>>> Once handlers well done, it is easy to add filters on top of it, same
>>>> kind
>>>>> of API but it takes another optional parameter:
>>>>>
>>>>> CompletionStage<Response> onRequest(Request request,
>>>>> Supplier<CompletionStage<Response>> proceed);
>>>>>
>>>>> with proceed the call to filter N+1 and finally the handler (check out
>>>> OWB
>>>>> interceptor impl, it is exactly the same.
>>>>>
>>>>> Last important point: ensure to handle @Priority (or add priority = int
>>>>> in @HttpHandler) cause when you will implement the matching chain you
>>>> will
>>>>> need an order normally.
>>>>>
>>>>> Bonus: you can make the matching strategies pluggable if you want and
>>>> just
>>>>> provide some defaults OOTB.
>>>>>
>>>>> Hope it makes sense.
>>>>>
>>>>> Romain Manni-Bucau
>>>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>>>> <http://rmannibucau.wordpress.com> | Github <
>>>> https://github.com/rmannibucau> |
>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>>>
>>>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org>
>> a
>>>>> écrit :
>>>>>
>>>>>> Hello everyone,
>>>>>>
>>>>>> in the last month I have spent most of my time getting to know coding
>>>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
>>>>>> extensions which will be the technological foundation for the server.
>>>>>>
>>>>>> Next up will be defining and implementing the HTTP API, which will
>> bring
>>>>>> CDI and Netty together. Feel free to contribute your thoughts on the
>>>>>> matter here on the mailing list or in the respective Jira issue:
>>>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>>>>>
>>>>>> @Romain: can you share some ideas, annotations, interfaces for how you
>>>>>> see the API roughly? Any kind of formal requirement-proposal would be
>>>>>> helpful to start with.
>>>>>>
>>>>>> Thanks and best regards,
>>>>>> Alexander
>>>>>>
>>>>>>

Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Should matching be an array? If so how would you impl it? (it is associated
with "url" or another parameter for its config, for instance EXACT + path
so i don't see how it would work to support EXACT and WILDCARD at the same
time for ex).
In Request ensure to return Map<String, List<String>> and not
HashMap<String, String> (it is not a hashmap cause headers are case
insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO but
no need to expose the impl).
Parameters should likely be split in body parameters (form data) and query
parameters (so getParameter(String) would be a facade to 2 get in query and
form maps).
Kind of the same remark on the response (for HashMap) + payload is an
InputStream. This one requires some explanation:

1. Using a ByteArrayOutputStream is quite limiting since you drop all
decorations and oversized payload support
2. An outputstream requires the server to know how to map this object to
something readable (input stream or the reactive equivalent)
3. output stream will likely require the server to inject the instance once
1 is fixed which is something we should try to avoid

Now if you move to an Inputstream you can consumer it easily from the
server point of view, wrap it easily (in a filter for ex) and setting the
output is as easy:

setOutput(new ByteArrayInputStream(...));
+ the user friendly flavor(s): setOutput(String) (which does the
setoutput(inputStream) + setHeader(content-length))

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hey Romain,
>
> thanks for the feedback! I have implemented the API feedback now, please
> take another look:
> https://github.com/a-rekkusu/owb-centric-microserver
>
> Are there functionalities that you miss?
> Else, the Netty implementation ist next.
>
> Best regards,
> Alex
>
> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> > Hi Alex,
> >
> > I don't think you need the HttpHandler annotation to be a qualifier (will
> > typically end up on a method not producing any bean at some point I think
> > as in the example at the end of this answer).
> > I guess Request/Response models are not yet done? Side note before you
> work
> > on them: maybe don't copy servlet API, content-type, content-length etc
> are
> > just headers, no need to make them specific, also prefer to set the
> payload
> > (as an inputstream or reactive stream) rather than encapsulating
> read/write
> > methods, it enables a better composition and decoration in general and
> > bypasses to go through a provider/factory to create requests/responses.
> > Last thing is you probably want to create a package for that work and not
> > use the default one ;).
> >
> > Typically it is a good start IMHO and once this works I'd do another
> small
> > iteration to end up on:
> >
> > public class HelloWorldHandlerFuture
> > {
> > @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url = "/hello",
> > matching = Matching.EXACT)
> > public CompletionStage<Response> apply(Request request)
> > {
> > return CompletableFuture.supplyAsync(() ->
> > {
> > Response response = new Response();
> > response.setStatus(200);
> > response.write("Hello World from " + getClass().getName());
> > return response;
> > });
> > }
> > }
> >
> > Small side note (fully related to CompletionStage more than your current
> > work: if you want a synchronous impl of a CompletionStage you can use
> > CompletionFuture.completedFuture(response) - avoid the sypplyAsync - and
> if
> > you want to be async (sypplyAsync) ensure you pass an executor as second
> > parameter otherwise you end up being in default ForkJoinPool which has a
> > lot of side effects and limitations.
> >
> > Anyway, very good first iteration, it is pretty close to what I was
> > envisioning and it looks as smooth as I was thinking.
> >
> > Small tip for the impl phase (don't know if it is the next one or not):
> for
> > the handler registration, ensure to enable to do it programmatically:
> > register(Function<Request, CompletionStage<Response>>). It will enable to
> > use other models than the annotated one which is just a simplified API of
> > the actual one the server uses internally.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fi...@mailbox.org>
> a
> > écrit :
> >
> >> Hi Romain,
> >>
> >> I have made a first draft for the API and example showcase:
> >> https://github.com/a-rekkusu/owb-centric-microserver
> >>
> >> Please take a look and let me know what you think.
> >> CompletionStage is supported, but right now for all requests on a
> >> handler. If you would want a CompletableFuture only for POST for
> >> example, and not on GET, how do you think we should handle that?
> >> We could do it with a second HttpHandler on the same url but with the
> >> respective HttpMethod (e. g. HelloWorldHandlerGet /
> HelloWorldHandlerPost).
> >>
> >> Kind regards,
> >> Alex
> >>
> >> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> >>> Hi Alex,
> >>>
> >>> Nothing is written in the stone but here is how I would approach that:
> >>>
> >>> 1. Write a HTTP server able to call a handler to answer a request - you
> >> can
> >>> start by giving a hardcoded handler but in terms of design, ensure you
> >> get
> >>> something taking a Request abstracting as input and a Response
> >> abstraction
> >>> as output.
> >>> Netty has these abstraction but we don't want to depend on netty so you
> >>> should duplicate it making it even more user friendly (netty stays low
> >>> level).
> >>> 2. Make this server CDI friendly, basically a CDI bean and nice to
> have,
> >>> configurable (port, ssl, ...) with MP-Config (or equivalent - if you
> >> take a
> >>> Map<String, String> as input you won here),
> >>> 3. Now you have to abstract the handler and make the default handler a
> >>> facade for user handlers. User handlers are CDI beans. I would start by
> >>> making them with something between servlet and jaxrs:
> >>>
> >>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> >> Matching.EXACT)
> >>> method being the http method handled, url the urlpattern matched thanks
> >> the
> >>> matching algo (i used an enum but it can be anything equivalent). EXACT
> >>> means request path == url, we can envision wildcard matching (as in
> >>> servlet), regex matching etc...
> >>>
> >>> The signature can start to be the exact expected one
> >>> (CompletionStage<Response> onRequest(Request)) while validated in the
> cdi
> >>> extension grabbing the handlers, then you can relax the CompletionStage
> >>> requirement (Response onReq(Request)) and finally you can go closer to
> >>> jaxrs adding @PathParam/@QueryParam/... like annotations but if Request
> >> API
> >>> is nice enough it is not required in this layer - it can be a layer on
> >> top
> >>> as jaxrs is on top of servlet. What's important here is to be reactive
> >>> friendly by design - I'll let you play with the threading strategies to
> >>> have an useful CompletionStage and how to link it - or not ;) - to
> netty
> >>> executors.
> >>>
> >>> Once handlers well done, it is easy to add filters on top of it, same
> >> kind
> >>> of API but it takes another optional parameter:
> >>>
> >>> CompletionStage<Response> onRequest(Request request,
> >>> Supplier<CompletionStage<Response>> proceed);
> >>>
> >>> with proceed the call to filter N+1 and finally the handler (check out
> >> OWB
> >>> interceptor impl, it is exactly the same.
> >>>
> >>> Last important point: ensure to handle @Priority (or add priority = int
> >>> in @HttpHandler) cause when you will implement the matching chain you
> >> will
> >>> need an order normally.
> >>>
> >>> Bonus: you can make the matching strategies pluggable if you want and
> >> just
> >>> provide some defaults OOTB.
> >>>
> >>> Hope it makes sense.
> >>>
> >>> Romain Manni-Bucau
> >>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>
> >>>
> >>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org>
> a
> >>> écrit :
> >>>
> >>>> Hello everyone,
> >>>>
> >>>> in the last month I have spent most of my time getting to know coding
> >>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
> >>>> extensions which will be the technological foundation for the server.
> >>>>
> >>>> Next up will be defining and implementing the HTTP API, which will
> bring
> >>>> CDI and Netty together. Feel free to contribute your thoughts on the
> >>>> matter here on the mailing list or in the respective Jira issue:
> >>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>>>
> >>>> @Romain: can you share some ideas, annotations, interfaces for how you
> >>>> see the API roughly? Any kind of formal requirement-proposal would be
> >>>> helpful to start with.
> >>>>
> >>>> Thanks and best regards,
> >>>> Alexander
> >>>>
> >>>>
>

Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hey Romain,

thanks for the feedback! I have implemented the API feedback now, please
take another look:
https://github.com/a-rekkusu/owb-centric-microserver

Are there functionalities that you miss?
Else, the Netty implementation ist next.

Best regards,
Alex

On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> Hi Alex,
>
> I don't think you need the HttpHandler annotation to be a qualifier (will
> typically end up on a method not producing any bean at some point I think
> as in the example at the end of this answer).
> I guess Request/Response models are not yet done? Side note before you work
> on them: maybe don't copy servlet API, content-type, content-length etc are
> just headers, no need to make them specific, also prefer to set the payload
> (as an inputstream or reactive stream) rather than encapsulating read/write
> methods, it enables a better composition and decoration in general and
> bypasses to go through a provider/factory to create requests/responses.
> Last thing is you probably want to create a package for that work and not
> use the default one ;).
>
> Typically it is a good start IMHO and once this works I'd do another small
> iteration to end up on:
>
> public class HelloWorldHandlerFuture
> {
> @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url = "/hello",
> matching = Matching.EXACT)
> public CompletionStage<Response> apply(Request request)
> {
> return CompletableFuture.supplyAsync(() ->
> {
> Response response = new Response();
> response.setStatus(200);
> response.write("Hello World from " + getClass().getName());
> return response;
> });
> }
> }
>
> Small side note (fully related to CompletionStage more than your current
> work: if you want a synchronous impl of a CompletionStage you can use
> CompletionFuture.completedFuture(response) - avoid the sypplyAsync - and if
> you want to be async (sypplyAsync) ensure you pass an executor as second
> parameter otherwise you end up being in default ForkJoinPool which has a
> lot of side effects and limitations.
>
> Anyway, very good first iteration, it is pretty close to what I was
> envisioning and it looks as smooth as I was thinking.
>
> Small tip for the impl phase (don't know if it is the next one or not): for
> the handler registration, ensure to enable to do it programmatically:
> register(Function<Request, CompletionStage<Response>>). It will enable to
> use other models than the annotated one which is just a simplified API of
> the actual one the server uses internally.
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hi Romain,
>>
>> I have made a first draft for the API and example showcase:
>> https://github.com/a-rekkusu/owb-centric-microserver
>>
>> Please take a look and let me know what you think.
>> CompletionStage is supported, but right now for all requests on a
>> handler. If you would want a CompletableFuture only for POST for
>> example, and not on GET, how do you think we should handle that?
>> We could do it with a second HttpHandler on the same url but with the
>> respective HttpMethod (e. g. HelloWorldHandlerGet / HelloWorldHandlerPost).
>>
>> Kind regards,
>> Alex
>>
>> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
>>> Hi Alex,
>>>
>>> Nothing is written in the stone but here is how I would approach that:
>>>
>>> 1. Write a HTTP server able to call a handler to answer a request - you
>> can
>>> start by giving a hardcoded handler but in terms of design, ensure you
>> get
>>> something taking a Request abstracting as input and a Response
>> abstraction
>>> as output.
>>> Netty has these abstraction but we don't want to depend on netty so you
>>> should duplicate it making it even more user friendly (netty stays low
>>> level).
>>> 2. Make this server CDI friendly, basically a CDI bean and nice to have,
>>> configurable (port, ssl, ...) with MP-Config (or equivalent - if you
>> take a
>>> Map<String, String> as input you won here),
>>> 3. Now you have to abstract the handler and make the default handler a
>>> facade for user handlers. User handlers are CDI beans. I would start by
>>> making them with something between servlet and jaxrs:
>>>
>>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
>> Matching.EXACT)
>>> method being the http method handled, url the urlpattern matched thanks
>> the
>>> matching algo (i used an enum but it can be anything equivalent). EXACT
>>> means request path == url, we can envision wildcard matching (as in
>>> servlet), regex matching etc...
>>>
>>> The signature can start to be the exact expected one
>>> (CompletionStage<Response> onRequest(Request)) while validated in the cdi
>>> extension grabbing the handlers, then you can relax the CompletionStage
>>> requirement (Response onReq(Request)) and finally you can go closer to
>>> jaxrs adding @PathParam/@QueryParam/... like annotations but if Request
>> API
>>> is nice enough it is not required in this layer - it can be a layer on
>> top
>>> as jaxrs is on top of servlet. What's important here is to be reactive
>>> friendly by design - I'll let you play with the threading strategies to
>>> have an useful CompletionStage and how to link it - or not ;) - to netty
>>> executors.
>>>
>>> Once handlers well done, it is easy to add filters on top of it, same
>> kind
>>> of API but it takes another optional parameter:
>>>
>>> CompletionStage<Response> onRequest(Request request,
>>> Supplier<CompletionStage<Response>> proceed);
>>>
>>> with proceed the call to filter N+1 and finally the handler (check out
>> OWB
>>> interceptor impl, it is exactly the same.
>>>
>>> Last important point: ensure to handle @Priority (or add priority = int
>>> in @HttpHandler) cause when you will implement the matching chain you
>> will
>>> need an order normally.
>>>
>>> Bonus: you can make the matching strategies pluggable if you want and
>> just
>>> provide some defaults OOTB.
>>>
>>> Hope it makes sense.
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>> <http://rmannibucau.wordpress.com> | Github <
>> https://github.com/rmannibucau> |
>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>> <
>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>>
>>>
>>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org> a
>>> écrit :
>>>
>>>> Hello everyone,
>>>>
>>>> in the last month I have spent most of my time getting to know coding
>>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
>>>> extensions which will be the technological foundation for the server.
>>>>
>>>> Next up will be defining and implementing the HTTP API, which will bring
>>>> CDI and Netty together. Feel free to contribute your thoughts on the
>>>> matter here on the mailing list or in the respective Jira issue:
>>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>>>
>>>> @Romain: can you share some ideas, annotations, interfaces for how you
>>>> see the API roughly? Any kind of formal requirement-proposal would be
>>>> helpful to start with.
>>>>
>>>> Thanks and best regards,
>>>> Alexander
>>>>
>>>>

Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Alex,

I don't think you need the HttpHandler annotation to be a qualifier (will
typically end up on a method not producing any bean at some point I think
as in the example at the end of this answer).
I guess Request/Response models are not yet done? Side note before you work
on them: maybe don't copy servlet API, content-type, content-length etc are
just headers, no need to make them specific, also prefer to set the payload
(as an inputstream or reactive stream) rather than encapsulating read/write
methods, it enables a better composition and decoration in general and
bypasses to go through a provider/factory to create requests/responses.
Last thing is you probably want to create a package for that work and not
use the default one ;).

Typically it is a good start IMHO and once this works I'd do another small
iteration to end up on:

public class HelloWorldHandlerFuture
{
@HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url = "/hello",
matching = Matching.EXACT)
public CompletionStage<Response> apply(Request request)
{
return CompletableFuture.supplyAsync(() ->
{
Response response = new Response();
response.setStatus(200);
response.write("Hello World from " + getClass().getName());
return response;
});
}
}

Small side note (fully related to CompletionStage more than your current
work: if you want a synchronous impl of a CompletionStage you can use
CompletionFuture.completedFuture(response) - avoid the sypplyAsync - and if
you want to be async (sypplyAsync) ensure you pass an executor as second
parameter otherwise you end up being in default ForkJoinPool which has a
lot of side effects and limitations.

Anyway, very good first iteration, it is pretty close to what I was
envisioning and it looks as smooth as I was thinking.

Small tip for the impl phase (don't know if it is the next one or not): for
the handler registration, ensure to enable to do it programmatically:
register(Function<Request, CompletionStage<Response>>). It will enable to
use other models than the annotated one which is just a simplified API of
the actual one the server uses internally.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hi Romain,
>
> I have made a first draft for the API and example showcase:
> https://github.com/a-rekkusu/owb-centric-microserver
>
> Please take a look and let me know what you think.
> CompletionStage is supported, but right now for all requests on a
> handler. If you would want a CompletableFuture only for POST for
> example, and not on GET, how do you think we should handle that?
> We could do it with a second HttpHandler on the same url but with the
> respective HttpMethod (e. g. HelloWorldHandlerGet / HelloWorldHandlerPost).
>
> Kind regards,
> Alex
>
> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> > Hi Alex,
> >
> > Nothing is written in the stone but here is how I would approach that:
> >
> > 1. Write a HTTP server able to call a handler to answer a request - you
> can
> > start by giving a hardcoded handler but in terms of design, ensure you
> get
> > something taking a Request abstracting as input and a Response
> abstraction
> > as output.
> > Netty has these abstraction but we don't want to depend on netty so you
> > should duplicate it making it even more user friendly (netty stays low
> > level).
> > 2. Make this server CDI friendly, basically a CDI bean and nice to have,
> > configurable (port, ssl, ...) with MP-Config (or equivalent - if you
> take a
> > Map<String, String> as input you won here),
> > 3. Now you have to abstract the handler and make the default handler a
> > facade for user handlers. User handlers are CDI beans. I would start by
> > making them with something between servlet and jaxrs:
> >
> > @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> Matching.EXACT)
> >
> > method being the http method handled, url the urlpattern matched thanks
> the
> > matching algo (i used an enum but it can be anything equivalent). EXACT
> > means request path == url, we can envision wildcard matching (as in
> > servlet), regex matching etc...
> >
> > The signature can start to be the exact expected one
> > (CompletionStage<Response> onRequest(Request)) while validated in the cdi
> > extension grabbing the handlers, then you can relax the CompletionStage
> > requirement (Response onReq(Request)) and finally you can go closer to
> > jaxrs adding @PathParam/@QueryParam/... like annotations but if Request
> API
> > is nice enough it is not required in this layer - it can be a layer on
> top
> > as jaxrs is on top of servlet. What's important here is to be reactive
> > friendly by design - I'll let you play with the threading strategies to
> > have an useful CompletionStage and how to link it - or not ;) - to netty
> > executors.
> >
> > Once handlers well done, it is easy to add filters on top of it, same
> kind
> > of API but it takes another optional parameter:
> >
> > CompletionStage<Response> onRequest(Request request,
> > Supplier<CompletionStage<Response>> proceed);
> >
> > with proceed the call to filter N+1 and finally the handler (check out
> OWB
> > interceptor impl, it is exactly the same.
> >
> > Last important point: ensure to handle @Priority (or add priority = int
> > in @HttpHandler) cause when you will implement the matching chain you
> will
> > need an order normally.
> >
> > Bonus: you can make the matching strategies pluggable if you want and
> just
> > provide some defaults OOTB.
> >
> > Hope it makes sense.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org> a
> > écrit :
> >
> >> Hello everyone,
> >>
> >> in the last month I have spent most of my time getting to know coding
> >> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
> >> extensions which will be the technological foundation for the server.
> >>
> >> Next up will be defining and implementing the HTTP API, which will bring
> >> CDI and Netty together. Feel free to contribute your thoughts on the
> >> matter here on the mailing list or in the respective Jira issue:
> >> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>
> >> @Romain: can you share some ideas, annotations, interfaces for how you
> >> see the API roughly? Any kind of formal requirement-proposal would be
> >> helpful to start with.
> >>
> >> Thanks and best regards,
> >> Alexander
> >>
> >>
>

Re: GSOC 2020 progress update

Posted by Alexander Fischer <fi...@mailbox.org>.
Hi Romain,

I have made a first draft for the API and example showcase:
https://github.com/a-rekkusu/owb-centric-microserver

Please take a look and let me know what you think.
CompletionStage is supported, but right now for all requests on a
handler. If you would want a CompletableFuture only for POST for
example, and not on GET, how do you think we should handle that?
We could do it with a second HttpHandler on the same url but with the
respective HttpMethod (e. g. HelloWorldHandlerGet / HelloWorldHandlerPost).

Kind regards,
Alex

On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> Hi Alex,
>
> Nothing is written in the stone but here is how I would approach that:
>
> 1. Write a HTTP server able to call a handler to answer a request - you can
> start by giving a hardcoded handler but in terms of design, ensure you get
> something taking a Request abstracting as input and a Response abstraction
> as output.
> Netty has these abstraction but we don't want to depend on netty so you
> should duplicate it making it even more user friendly (netty stays low
> level).
> 2. Make this server CDI friendly, basically a CDI bean and nice to have,
> configurable (port, ssl, ...) with MP-Config (or equivalent - if you take a
> Map<String, String> as input you won here),
> 3. Now you have to abstract the handler and make the default handler a
> facade for user handlers. User handlers are CDI beans. I would start by
> making them with something between servlet and jaxrs:
>
> @HttpHandler(method = {GET, POST}, url = "/foo", mathing = Matching.EXACT)
>
> method being the http method handled, url the urlpattern matched thanks the
> matching algo (i used an enum but it can be anything equivalent). EXACT
> means request path == url, we can envision wildcard matching (as in
> servlet), regex matching etc...
>
> The signature can start to be the exact expected one
> (CompletionStage<Response> onRequest(Request)) while validated in the cdi
> extension grabbing the handlers, then you can relax the CompletionStage
> requirement (Response onReq(Request)) and finally you can go closer to
> jaxrs adding @PathParam/@QueryParam/... like annotations but if Request API
> is nice enough it is not required in this layer - it can be a layer on top
> as jaxrs is on top of servlet. What's important here is to be reactive
> friendly by design - I'll let you play with the threading strategies to
> have an useful CompletionStage and how to link it - or not ;) - to netty
> executors.
>
> Once handlers well done, it is easy to add filters on top of it, same kind
> of API but it takes another optional parameter:
>
> CompletionStage<Response> onRequest(Request request,
> Supplier<CompletionStage<Response>> proceed);
>
> with proceed the call to filter N+1 and finally the handler (check out OWB
> interceptor impl, it is exactly the same.
>
> Last important point: ensure to handle @Priority (or add priority = int
> in @HttpHandler) cause when you will implement the matching chain you will
> need an order normally.
>
> Bonus: you can make the matching strategies pluggable if you want and just
> provide some defaults OOTB.
>
> Hope it makes sense.
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org> a
> écrit :
>
>> Hello everyone,
>>
>> in the last month I have spent most of my time getting to know coding
>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
>> extensions which will be the technological foundation for the server.
>>
>> Next up will be defining and implementing the HTTP API, which will bring
>> CDI and Netty together. Feel free to contribute your thoughts on the
>> matter here on the mailing list or in the respective Jira issue:
>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>>
>> @Romain: can you share some ideas, annotations, interfaces for how you
>> see the API roughly? Any kind of formal requirement-proposal would be
>> helpful to start with.
>>
>> Thanks and best regards,
>> Alexander
>>
>>

Re: GSOC 2020 progress update

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi Alex,

Nothing is written in the stone but here is how I would approach that:

1. Write a HTTP server able to call a handler to answer a request - you can
start by giving a hardcoded handler but in terms of design, ensure you get
something taking a Request abstracting as input and a Response abstraction
as output.
Netty has these abstraction but we don't want to depend on netty so you
should duplicate it making it even more user friendly (netty stays low
level).
2. Make this server CDI friendly, basically a CDI bean and nice to have,
configurable (port, ssl, ...) with MP-Config (or equivalent - if you take a
Map<String, String> as input you won here),
3. Now you have to abstract the handler and make the default handler a
facade for user handlers. User handlers are CDI beans. I would start by
making them with something between servlet and jaxrs:

@HttpHandler(method = {GET, POST}, url = "/foo", mathing = Matching.EXACT)

method being the http method handled, url the urlpattern matched thanks the
matching algo (i used an enum but it can be anything equivalent). EXACT
means request path == url, we can envision wildcard matching (as in
servlet), regex matching etc...

The signature can start to be the exact expected one
(CompletionStage<Response> onRequest(Request)) while validated in the cdi
extension grabbing the handlers, then you can relax the CompletionStage
requirement (Response onReq(Request)) and finally you can go closer to
jaxrs adding @PathParam/@QueryParam/... like annotations but if Request API
is nice enough it is not required in this layer - it can be a layer on top
as jaxrs is on top of servlet. What's important here is to be reactive
friendly by design - I'll let you play with the threading strategies to
have an useful CompletionStage and how to link it - or not ;) - to netty
executors.

Once handlers well done, it is easy to add filters on top of it, same kind
of API but it takes another optional parameter:

CompletionStage<Response> onRequest(Request request,
Supplier<CompletionStage<Response>> proceed);

with proceed the call to filter N+1 and finally the handler (check out OWB
interceptor impl, it is exactly the same.

Last important point: ensure to handle @Priority (or add priority = int
in @HttpHandler) cause when you will implement the matching chain you will
need an order normally.

Bonus: you can make the matching strategies pluggable if you want and just
provide some defaults OOTB.

Hope it makes sense.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fi...@mailbox.org> a
écrit :

> Hello everyone,
>
> in the last month I have spent most of my time getting to know coding
> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
> extensions which will be the technological foundation for the server.
>
> Next up will be defining and implementing the HTTP API, which will bring
> CDI and Netty together. Feel free to contribute your thoughts on the
> matter here on the mailing list or in the respective Jira issue:
> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
>
> @Romain: can you share some ideas, annotations, interfaces for how you
> see the API roughly? Any kind of formal requirement-proposal would be
> helpful to start with.
>
> Thanks and best regards,
> Alexander
>
>