On Mon, Jun 11, 2018 at 5:44 AM, Thorsten Schöning <tschoen...@am-soft.de>
wrote:

> Guten Tag Thorsten Schöning,
> am Donnerstag, 7. Juni 2018 um 18:58 schrieben Sie:
>
> > So "7.1. Custom client connections" seem to be the way to go: Provide
> > a custom HttpConnectionFactory and make Axis2 to use that, while I've
> > already provided a custom connection manager to Axis2 in the past with
> > non-default settings. What I'm missing currently is the part where the
> > request body gets serialized, "DefaultHttpRequestWriterFactory" reads
> > like it only handles headers...
>
> > https://hc.apache.org/httpcomponents-client-ga/
> tutorial/html/advanced.html#d5e913
>
> The important part to understand seems to be that the connection
> factory provides some instances of "HttpClientConnection" in the end
> and those distinguishe between serializing headers and bodies:
>
> https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/
> http/HttpClientConnection.html#sendRequestHeader(org.
> apache.http.HttpRequest)
> https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/
> http/HttpClientConnection.html#sendRequestEntity(org.apache.http.
> HttpEntityEnclosingRequest)
>
> The request writers are only used in "sendRequestHeader", while bodies
> are serialized using whatever body-containing object is given. In case
> of Axis2 this seems to be "AxisRequestEntityImpl", which takes care of
> serializing according to some "MessageFormatter", which itself exists
> for various different formats like JSON and SOAP and things like MTOM
> vs. inline vs. SOAP with attachments are handled somewhere in that
> chain as well...
>
> In the end, every data is written to a stream created within
> "sendRequestEntity" and that seems to be a good place to put a rate
> limiter in:
>
> >     @Override
> >     public void sendRequestEntity(final HttpEntityEnclosingRequest
> request)
> >             throws HttpException, IOException {
> >         Args.notNull(request, "HTTP request");
> >         ensureOpen();
> >         final HttpEntity entity = request.getEntity();
> >         if (entity == null) {
> >             return;
> >         }
> >         final OutputStream outstream = prepareOutput(request);
> >         entity.writeTo(outstream);
> >         outstream.close();
> >     }
>
> >     protected OutputStream createOutputStream(
> >             final long len,
> >             final SessionOutputBuffer outbuffer) {
> >         if (len == ContentLengthStrategy.CHUNKED) {
> >             return new ChunkedOutputStream(2048, outbuffer);
> >        } else if (len == ContentLengthStrategy.IDENTITY) {
> >             return new IdentityOutputStream(outbuffer);
> >         } else {
> >             return new ContentLengthOutputStream(outbuffer, len);
> >         }
> >     }
>
> >     protected OutputStream prepareOutput(final HttpMessage message)
> throws HttpException {
> >         final long len = this.outgoingContentStrategy.
> determineLength(message);
> >         return createOutputStream(len, this.outbuffer);
> >     }
>
> So, the connection factory is needed to provide custom client
> connections and one needs to create one which overrides
> "createOutputStream" by calling the super implementation and
> afterwards wrapping the resulting "OutputStream" once more in some
> "RateLimitOutputStream" or such.
>
> From my understanding, that "RateLimitOutputStream" would "only" need
> to make sure that writes are somewhat small, so that not e.g. 1 GB of
> data is transferred during one call, but smaller blocks of some kB or
> MB or such. Each transfer of some small block is forwarded to the
> wrapped "OutputStream" after some rate limiting resources have been
> aquired like in the following example:
>
> https://stackoverflow.com/a/6271935/2055163
>
> For that to work, transfers need to be small enough to actually make
> subsequent calls to aquire resources wait. One large call with 1 GB of
> data would transfer that 1 GB and make calls afterwards wait, which
> might never occur because the 1 GB of data already has been
> transferred. From what I've seen in the sources of Axis2 and
> HTTPComponents, things should get called already with small chunks of
> data because of the usage of "DataHandler".
>
> Not sure if there's an easier way, better ideas welcome. :-)
>

Its been many years since I used attachments though I was using them for
bit around the time when axis2 first came out.

You seem to be on the right path as your code shows the choices between
using chunked or content-length. And the DataHandler is the other low
hanging fruit place to tweak. MessageFormatter is the heart of the GSON
module that I am using a lot right now and yes, that is another place to
look at customization. .

Since this is http you may have to tweak the timeout.

Large attachments is a subject that comes up occasionally, let us know how
it turns out.

Regards,
Robert


> Mit freundlichen Grüßen,
>
> Thorsten Schöning
>
> --
> Thorsten Schöning       E-Mail: thorsten.schoen...@am-soft.de
> AM-SoFT IT-Systeme      http://www.AM-SoFT.de/
>
> Telefon...........05151-  9468- 55
> Fax...............05151-  9468- 88
> Mobil..............0178-8 9468- 04
>
> AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
> AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-dev-unsubscr...@axis.apache.org
> For additional commands, e-mail: java-dev-h...@axis.apache.org
>
>

Reply via email to