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 <fische...@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 <fische...@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 <fische...@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 <
>> fische...@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
>>>>>>>>
>>>>>>>>

Reply via email to